Как освободить объект при использовании обратного вызова блока - PullRequest
5 голосов
/ 24 мая 2011

это, вероятно, вопрос новичка относительно управления памятью.

Как я могу освободить объект при использовании блоков в качестве обратного вызова в цели c?

(обновленный код)

@implementation ObjectWithCallback
- (void)dealloc {
    [_completionHandler release];
    [super dealloc];
}
- (void)doTaskWithCompletionHandler:(void(^)(void))handler {
    _completionHandler = [handler copy];
    // Start tasks...
}
- (void)tasksDone {
    // Do callback block
    _completionHandler();
    // Delete reference to block
    [_completionHandler release];
    _completionHandler = nil;
}

// Use of the ObjectWithCallback
ObjectWithCallback *request = [[ObjectWithCallback alloc] init];
[request doTaskWithCompletionHandler:^(void){
    // Callback called and task is ready.
}];

1 Ответ

11 голосов
/ 24 мая 2011

Быстрый, неполный ответ: [request autorelease]

Проблема в том, что блоки неявно сохраняют любые объекты, на которые есть ссылки в теле блока.Таким образом, блок сохраняет request, а request сохраняет блок, что приводит к циклу сохранения, и никто не освобождается.

Чтобы исправить это, вы объявляете переменную request как __block, что предотвращаетблок сохранения захваченного объекта:

__block ObjectWithCallback *request = [[ObjectWithCallback alloc] init];

Рекомендуемое прочтение:

...