Управление памятью с помощью блока и ARC, утечка? - PullRequest
2 голосов
/ 22 февраля 2012

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

Примечание: прибор не имеет утечек.

Код метода aaa: некоторого класса A:

- (void) aaa {
   NSString *path = ...something...;

   NSBlockOperation* theOp = [NSBlockOperation blockOperationWithBlock: ^{
   // using path
   [self somethingElseWith:path];
   }];

   [self.aQueue addOperation:theOp];
}

Итак, я создаю блок для установки aQueue (NSOperationQueue *). Цель состоит в том, чтобы разгрузить из основного потока долго выполняющийся метод SomeElseWith: так, чтобы графический интерфейс продолжал реагировать.

Внутри блока я ссылаюсь на локальный var "путь", который будет выходить за пределы области в конце метода aaa:.

Если я правильно прочитал документ, блок сохранит «путь». Но ARC вставляет релиз в конце этого блока неявно? Было бы логично и приятно.

Или я должен объявить «путь» как __block и присвоить его nil в конце моего блока? (Инструкция ...)

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

Ответы [ 2 ]

6 голосов
/ 22 февраля 2012

С переменной path все в порядке. Однако вам может потребоваться избежать цикла сохранения, используя weak ссылку на self. Если aQueue является ссылкой strong, возможно, существует цикл сохранения, в результате которого self никогда не будет разблокирован.

Решение:

- (void) aaa {
   NSString *path = ...something...;

   __weak id self_ = self;
   NSBlockOperation* theOp = [NSBlockOperation blockOperationWithBlock: ^{
   // using path
   [self_ somethingElseWith:path];
   }];

   [self.aQueue addOperation:theOp];
}

Убедитесь, что операция не вызывается после того, как класс больше не существует.

3 голосов
/ 22 февраля 2012

Блок будет автоматически обрабатывать управление памятью для любых локальных пользователей из окружающей области. Вам не нужно беспокоиться о сохранении / освобождении пар в этом случае. Обратите внимание, что path будет const в пределах блока. Если вам нужно, чтобы path был изменяемым в пределах блока, используйте атрибут __block.

Различные способы, которыми блок обрабатывает переменные, подробно описаны здесь: блоки и переменные

...