Как освободить объект с обработчиком завершения блока в ARC? - PullRequest
9 голосов
/ 04 января 2012

В моем коде часто встречается схема выделения объекта, позволяющая ему что-то делать с обработчиком завершения и освобождать его в обработчике:

LongOperation *foo = [[LongOperation alloc] init];
[foo runWithCompletion:^{
    // run some code and then:
    [foo autorelease];
}];

Это работает довольно хорошо, но когда я пытаюсь преобразовать код в ARC, Xcode справедливо жалуется, что он не может просто удалить autorelease из блока, так как это приведет к тому, что объект foo будет освобожден после выхода сфера.

Так, что является хорошим способом написать этот тип паттерна под ARC? Я мог бы ввести переменную экземпляра для foo:

[self setFoo:[[LongOperation alloc] init]];
[foo runWithCompletion:^{
    // run some code and then:
    [self setFoo:nil];
}];

… но код больше не будет возвращаться.

1 Ответ

5 голосов
/ 04 января 2012

В большинстве случаев это должно работать (т. Е. Если что-либо ссылается на себя внутри foo, foo продлится достаточно долго, чтобы удовлетворить этот код, прежде чем уйти). Если есть проблемы со слабыми ссылками и такие, что foo выглядит так, как будто он должен исчезнуть, но не должен до тех пор, пока не запустится обработчик, вы можете сделать что-то вроде:

__block LongOperation* foo = [[LongOperation alloc] init];
[foo runWithCompletion:^{
  // do some things
  foo = nil;
}];

Обратите внимание, что это своего рода противоположность этому шаблону, который заставляет объект / не / быть захвачен в соответствии с правилами управляемой памяти.

...