блоки и ARC - копирование или сбой при сборке релиза (вызвано уровнем оптимизации)

Я использую Xcode 4.3.3 и разрабатываю для iOS 5.0+. При разработке приложения ARC для iOS я начал использовать блоки в качестве механизма обратного вызова для асинхронных операций. Приложение отлично работает в симуляторе и на устройстве.

Затем я запустил его в качестве профилировщика в первый раз, и он сразу же начал падать на меня - в частности, EXC_BAD_ACCESS при попытке вызвать первый блок обратного вызова.

После небольшого исследования стало ясно, что различие в поведении объясняется тем, что профилировщик работает в «режиме выпуска». по умолчанию - в частности, с уровнем оптимизации, установленным на «Fastest, Smallest [-Os]» & quot; вместо "Нет [-O0]".

Например, следующий код (упрощенный для этого вопроса) вылетает при попытке выполнить callbackBlock:

- (void) setCallbackBlock:(void (^)(NSString *input))block
{
    callbackBlock = block;
}

- (void) invokeCallbackWithInput:(NSString *)input
{
    if (callbackBlock) {
        callbackBlock(input);
    }
}

Отладка в нем, вызов setCallbackBlock с уровнем оптимизации, установленным на «None», входящий блок будетNSStackBlockи callbackBlock станетNSMallocBlock.

Однако с уровнем оптимизации «Самый быстрый, самый маленький» он оставалсяNSStackBlock.

Изменение установочного кода для использования[block copy] решает проблему сбоя (на основеiOS 5 блокирует сбой только с Release Build).

Однако другой связанный с этим вопрос указывает на то, что это не должно быть необходимо с ARC - переменные блока копируются в кучу в ARC -Почему блок Objective-C все еще работает, не копируя его в кучу?

Итак, мой вопрос: что здесь происходит и почему? (Кроме того, как оба эти ответа могут быть правильными ...?)

Edit: To clarify how callbackBlock is being declared - just above my @implementation where those methods are is this:

@interface MyClass ()
{
    void (^callbackBlock)(NSString *input);
}

@end

Ответы на вопрос(2)

Ваш ответ на вопрос