Bloques y ARC: copie o bloquee con la versión de lanzamiento (causada por el nivel de optimización)

Estoy usando Xcode 4.3.3 y desarrollando para iOS 5.0+. En el desarrollo de una aplicación ARC iOS, comencé a usar bloques como un mecanismo de devolución de llamada para operaciones asíncronas. La aplicación funciona bien en el simulador y en el dispositivo.

Luego lo ejecuté en el perfilador por primera vez, y comenzó a fallar casi de inmediato, en particular, un EXC_BAD_ACCESS cuando intentaba invocar el primer bloque de devolución de llamada.

Después de una pequeña investigación, quedó claro que la diferencia en el comportamiento se debía a que el generador de perfiles se ejecuta en "Modo de lanzamiento" de forma predeterminada, en particular, con el Nivel de optimización establecido en "Más rápido, más pequeño [-Os]" en lugar de "Ninguno [-O0] ".

Por ejemplo, el siguiente código (simplificado para esta pregunta) se bloquearía al intentar ejecutar el callbackBlock:

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

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

Depurando en él, llamando a setCallbackBlock con el nivel de optimización establecido en "Ninguno", el bloque entrante sería unNSStackBlock, y el callbackBlock se convertiría en unNSMallocBlock.

Sin embargo, con el Nivel de optimización "Más rápido, más pequeño", se mantuvoNSStackBlock.

Cambiando el código de setter para usar[block copy] soluciona el problema de colisión (basado en5 bloques de iOS solo se bloquean con Build Build).

Sin embargo, otra pregunta relacionada indica que esto no debería ser necesario con ARC: las variables de bloque se copian al montón en ARC -¿Por qué el bloque Objective-C todavía funciona sin copiarlo en el montón?

Así que mi pregunta: ¿Qué está pasando aquí, y por qué? (Además, ¿cómo pueden ser correctas ambas respuestas ...?)

Editar: Para aclarar cómo se está declarando callbackBlock, justo encima de mi @implementación donde están esos métodos es esto:

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

@end

Respuestas a la pregunta(2)

Su respuesta a la pregunta