NSFileCoordinator утечка - PullRequest
       18

NSFileCoordinator утечка

3 голосов
/ 07 ноября 2011

Это один тривиальный вопрос управления памятью, связанный с блоками, и я не уверен, когда / где fc должен быть освобожден

NSFileCoordinator *fc = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
NSError *error = nil;
[fc coordinateWritingItemAtURL:sourceURL
                       options:NSFileCoordinatorWritingForDeleting
                         error:&error
                    byAccessor:^(NSURL *newURL) {

            // if error is not nil this block will not be called
            NSError *anError = nil;
            NSFileManager *fm = [NSFileManager defaultManager];
            [fm removeItemAtURL:newURL error:&anError];
            dispatch_async(q_main, ^{
                // change to the main queue and update the UI
                completion(anError);
        });
        // *** (1) Release here ? ***
        // [fc release];
        }];

// *** (2) or Release here ? ***
// [fc release]

if (error) {
    // change to the main queue and update the UI
    dispatch_async(q_main, ^{
        completion(error);
    });
}

Я думаю, что выпуск в (1) будет в порядке (без утечек), но действительно ли это стандартный способ работы? (освобождение объекта в блоке, который вызывает тот же объект ??). Я чувствую некоторую странность здесь.

В (2), также в порядке, но только потому, что блок доступа вызывается синхронно.

В целях обучения ... что если этот блок доступа будет называться асинхронно ? (В воображаемом случае нет необходимости в NSFileCoordinator). В таком случае мне нужно было бы сделать fc иваром или это просто в качестве первого подхода?

Любая помощь приветствуется

:)

1 Ответ

2 голосов
/ 07 ноября 2011

Для данного кода я бы выпустил в (2).Если вы отпустите кнопку (1), вы можете вырвать fc из-под себя.Нет способа узнать, что может понадобиться fc после вызова блока.

Для асинхронного случая я использовал такой код (хотя и не с NSFileCoordinator):

__block NSWindowController *wc = [[NSWindowController alloc] initWithWindowNibName:@"foo"];
[NSApp beginSheet:[wc window] modalForWindow:[self window] completionHandler:^(NSInteger returnCode) {
    if(NSOKButton == returnCode) {
      // Do something
    }
    [wc release], wc = nil;
  }];

-beginSheet:modalForWindow:completionHandler: - это категория, которую я добавил в NSApplication.

...