Blöcke und ARC - Kopieren oder Abstürzen mit Release Build (verursacht durch Optimierungslevel)

Ich verwende Xcode 4.3.3 und entwickle für iOS 5.0+. Bei der Entwicklung einer ARC iOS-Anwendung habe ich damit begonnen, Blöcke als Rückrufmechanismus für asynchrone Vorgänge zu verwenden. Die App funktioniert einwandfrei im Simulator und auf dem Gerät.

Dann habe ich den Profiler zum ersten Mal ausgeführt und fast sofort einen Absturz festgestellt - insbesondere einen EXC_BAD_ACCESS beim Versuch, den ersten Callback-Block aufzurufen.

Nach einer kurzen Untersuchung stellte sich heraus, dass der Profiler standardmäßig im "Freigabemodus" ausgeführt wird, insbesondere mit der Optimierungsstufe "Schnellste, Kleinste [-Os]" anstelle von "Keine [-O0] ".

Der folgende Code (für diese Frage vereinfacht) würde beispielsweise abstürzen, wenn versucht wird, den callbackBlock auszuführen:

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

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

Beim Debuggen, Aufrufen von setCallbackBlock mit der Optimierungsstufe "None" (Keine), wäre der eingehende Block einNSStackBlockund der callbackBlock würde einNSMallocBlock.

Mit der Optimierungsstufe "Schnellste, Kleinste" blieb es jedoch eineNSStackBlock.

Ändern des zu verwendenden Einstellcodes[block copy] behebt das Absturzproblem (basierend aufiOS 5-Blöcke stürzen nur mit Release Build ab).

Eine andere verwandte Frage weist jedoch darauf hin, dass dies bei ARC nicht erforderlich sein sollte - Blockvariablen werden in ARC auf den Heap kopiert -Warum funktioniert der Objective-C-Block immer noch, ohne ihn auf den Heap zu kopieren?

Also meine Frage: Was ist hier los und warum? (Wie können diese beiden Antworten auch richtig sein ...?)

Bearbeiten: Um zu verdeutlichen, wie callbackBlock deklariert wird - direkt über meiner @Implementierung, wo sich diese Methoden befinden, ist dies:

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

@end

Antworten auf die Frage(2)

Ihre Antwort auf die Frage