Подтвердить что ты не робот

В ARC, блоки автоматически копируются при назначении на ivar напрямую?

Предположим, что следующий код под ARC,

typedef void (^MyResponseHandler) (NSError *error);
@interface MyClass : NSObject
{
    MyResponseHandler _ivarResponseHandler;
}

- (void)myMethod:(MyResponseHandler)responseHandler
{
    _ivarResponseHandler = responseHandler;
    ...
}

Вопрос. Является ли блок автоматически скопирован в кучу при присвоении ivar?

Мой предыдущий вопрос подразумевал, что он копируется при назначении через @property. Но сегодня я использовал приведенный выше код и получил EXC_BAD_ACCESS, который был исправлен путем изменения на

_ivarResponseHandler = [responseHandler copy].

4b9b3361

Ответ 1

Изменить: мой предыдущий ответ был, скорее всего, неправильным.

Некоторые выбранные выдержки из ARC docs говорят:

3. Сохраняемые указатели объектов

Сохраняемый указатель объекта (или сохраняемый указатель) - это значение типа сохраняемого типа объекта (сохраняемый тип). Существует три типа сохраняемых типов указателей объектов:

  • указатели блоков (сформированные путем применения синтаксиса объявления каретки (^) к типу функции)

4.2. Семантика

Присвоение выполняется при оценке оператора присваивания. Семантика варьируется в зависимости от квалификации:

  • Для объектов __strong новый указатель сначала сохраняется; во-вторых, lvalue загружается примитивной семантикой; в-третьих, новый указатель хранится в lvalue с примитивной семантикой; и, наконец, старый пункт был выпущен. Это не выполняется атомарно; внешняя синхронизация должна использоваться, чтобы сделать это безопасным в условиях одновременных нагрузок и хранилищ.

4.4.1. Объекты

Если объект объявлен с типом владельца сохраняемого объекта, но без явного классификатора прав, его тип неявно скорректирован, чтобы иметь квалификацию __strong.

7.5. Блоки

За исключением сохранения в качестве части инициализации переменной параметра __strong или чтения переменной __weak, всякий раз, когда эти семантики требуют сохранения значения типа указателя блока, он имеет эффект Block_copy. Оптимизатор может удалить такие копии, когда видит, что результат используется только в качестве аргумента для вызова.

Итак, я думаю, что ответ может быть, в зависимости от оптимизатора.

Ответ 2

Ваша проблема и решение указывают, что мой ответ на ваш другой вопрос, вероятно, был неправильным. Я основывал его на последнем параграфе раздела 7.5 clang Objective-C Автоматическая документация подсчета ссылок:

За исключением сохранений, выполняемых как часть инициализации переменной параметра __strong или чтения переменной __weak, всякий раз, когда эти семантики требуют сохранения значения типа блока-указателя, он имеет эффект Block_copy, Оптимизатор может удалить такие копии, когда видит, что результат используется только в качестве аргумента для вызова.

Я взял "эту семантику" для обозначения всего документа, но если "эта семантика" относится только к разделу 7.5, тогда ARC только вставляет Block_copy для блока, который захватывается блоком.