Другой вариант будет:
NSOperationSubclass *operation = [[NSOperationSubclass alloc] init];
__weak NSOperationSubclass *weakOperation = operation;
[operation setCompletionBlock:^{
NSOperationSubclass *strongOperation = weakOperation;
dispatch_async(dispatch_get_main_queue(), ^{
assert(strongOperation != nil);
...
});
}];
[operationQueue addOperation:operation];
Я предполагаю, что вы также добавляете объект операции в NSOperationQueue. В этом случае очередь сохраняет операцию. Вероятно, он также сохраняется во время выполнения блока завершения (хотя я не нашел официального подтверждения о блоке завершения).
Но внутри вашего блока завершения создается другой блок. Этот блок будет запущен в определенный момент времени позже, возможно, после того, как завершится блок завершения NSOperations. Когда это произойдет, operation
будет освобождено очередью, а weakOperation
будет nil
. Но если мы создадим другую сильную ссылку на тот же объект из блока завершения операции, мы убедимся, что operation
будет существовать при запуске второго блока, и избежим сохранения цикла, потому что мы не фиксируем переменную operation
блоком .
Apple предоставляет этот пример в Переход к примечаниям к выпуску ARC см. Последний фрагмент кода в Использование классификаторов продолжительности жизни для избежания сильных циклов ссылок .