«Свойство сохраненного блока не копирует блок — вместо этого используйте атрибут копирования

У меня большой опыт работы с JavaScript, и я как можно лучше перехожу на Objective-C. Естественно, я всегда хватаюсь за возможность использовать замыкающие функции в моем исходном коде, например:

@property (nonatomic, retain) void (^zoomCallback)(NSInteger width, NSInteger height, NSString *url);

Однако каждый раз, когда я записываю это в Xcode, он предупреждает меня:

Свойство Retained block не копирует блок — вместо этого используйте атрибут copy

Насколько я понимаю, вам больше не нужно сохранять вещи вручную в Objective-C из-за ARC, поэтому я, по общему признанию, довольно удивлен этим предупреждением. Я предполагаю, что по блоку это относится к моей функции закрытия, поэтому, насколько я могу интерпретировать, это говорит мне, что назначение этой переменной:

myObject.zoomCallback = someMethod;

Также приведет к тому, что someMethod будет сохранен, и, таким образом, владелец someMethod продолжит существовать? Я правильно понял?

Каковы негативные последствия этого? Если я «скопирую» блок, не позволит ли он уничтожить владельца someMethod, и, таким образом, в самом методе закрытия каждый раз, когда я ссылаюсь на «я», он больше не будет существовать? Разве я не хочу почти всегда сохранять блок, если только мой метод закрытия не делает что-то очень тривиальное или что-то, что не ссылается на переменные-члены или методы?


person David Zorychta    schedule 04.08.2013    source источник
comment
Блоки не должны сохраняться, их нужно копировать. Замените retain на copy, чтобы решить эту проблему.   -  person Sergey Kalinichenko    schedule 04.08.2013
comment
Если вы используете ARC, вы также должны писать strong вместо retain.   -  person jscs    schedule 04.08.2013
comment
но почему же, какая разница, какая разная бывает?   -  person David Zorychta    schedule 04.08.2013
comment
@Skippy: тег xcode здесь не подходит, так как это IDE, а Macmee обсуждает функцию времени выполнения. Остается открытым вопрос, уместно ли удаление этого тега (слишком незначительное или нет) в предлагаемом редактировании.   -  person Michael Petrotta    schedule 04.08.2013


Ответы (1)


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

person Wain    schedule 04.08.2013