Die Verwendung von Blocks stürzt in iPhone Simulator 4.3 / XCode 4.2 und 4.0.2 ab

7

Hat jemand sonst Probleme mit dem 4.3 iPhone Simulator in XCode 4.2 (Löwe) oder 4.0.2?

Ich habe Code, der schon lange funktioniert, getestet wurde und in der Produktion Blöcke verwendet, um Abschlussaktionen zu spezifizieren. Zum Beispiel verwende ich UIView animate, um einen Text oben auf dem Etikett wie folgt auszublenden:

%Vor%

Ich bekomme EXEC_BAD_ACCESS zuverlässig im Simulator - nie ein Problem auf dem Gerät.

An einer anderen Stelle verwende ich meine eigene Completion-Block-Implementierung, um Maßnahmen zu ergreifen, nachdem der Benutzer eine modale Ansicht abgewiesen hat.

%Vor%

Es werden keine NSZombies angezeigt und der Analyzer läuft sauber. Außerdem wurde dieser Code 6 Monate lang ohne Abstürze produziert.

Hat sonst jemand diese Probleme? Es ist passiert, seit ich XCode aktualisiert habe.

    
David Hersey 18.07.2011, 20:15
quelle

1 Antwort

22

Soweit mir bekannt ist, handelt es sich um ein bekanntes Problem, das nur den 4.3-Simulator betrifft. Die Versionen 4.2 und Prerelease 5.0 scheinen dieses Problem nicht aufzuweisen. Allerdings ist es jetzt eher ein Problem, dass Lion ausfällt, da die neueste Version von Xcode nur den 4.3-Simulator unterstützt, in dem dieses Problem auftritt.

Die eigentliche Ursache liegt in den Hooks zwischen den Blöcken und den ObjC-Laufzeiten. Blöcke selbst funktionieren einwandfrei, aber jeder Versuch, eine Objective-C-Nachricht für sie aufzurufen, führt zu einem segfault. Dies liegt daran, dass die Block-Laufzeit einige nicht initialisierte Verweise auf die relevanten ObjC-Klassen enthält, und auf dem iOS 4.3-Simulator wurden diese nie initialisiert, wenn die ObjC-Laufzeit geladen wird (sie werden nur initialisiert, wenn ObjC überhaupt verwendet wird) Die Laufzeit des Blocks hängt nicht davon ab, dass Foundation geladen ist. Sie können dies zur Laufzeit überprüfen, indem Sie den Wert für _NSConcreteStackBlock , _NSConcreteGlobalBlock und _NSConcreteMallocBlock im Debugger betrachten. Im 4.2-Simulator oder auf dem Gerät werden diese Werte nicht Null sein, aber auf dem 4.3-Simulator sind sie noch Null.

Ich habe eine mögliche Lösung, auf die ich hier verlinken werde, aber zuerst versuche ich & amp; squeeze einige Informationen aus Apple, ob sie eine Korrektur an der Schwelle der Veröffentlichung haben oder wenn sie weitere Informationen benötigen, usw.

UPDATE: PROBLEM LÖSEN

Ich habe viel gegraben, und es läuft letztlich darauf hinaus: nicht schwach Link gegen libSystem.dylib mit -weak_library . Stattdessen sollten Sie entweder libSystem überhaupt nicht lockern (ich musste es bei der Unterstützung von iOS 3.1.x tun, da Compiler-generierter Block-Code in einem iOS4-spezifischen bedingten Code einen Verbindungsfehler zum Startzeitpunkt verursachte, dh einen schlechten Absturz) ), oder Sie sollten stattdessen -weak lSystem verwenden, was der Simulator besser versteht.

Wenn Sie im iOS Simulator arbeiten, können Sie sich die geladenen Bibliotheken ansehen (in Xcode: 'Produkt- & gt; Debug- & gt; Gemeinsame Bibliotheken ...') und wenn Sie nach 'Blocks' suchen, werden Sie sehen zwei Elemente: libsystem_blocks.dylib und libsystem_sim_blocks.dylib . Letzteres ist dasjenige, das von CoreFoundation verbunden wird, das den ObjC-Laufzeitkleber für die Laufzeit des Blocks initialisiert. Da Sie jedoch die libSystem -Bibliothek als Ganzes schwach verknüpfen, werden die Symbole, die normalerweise von der Version des Simulators überschrieben werden (da sie später als libSystem geladen werden), tatsächlich zur Laufzeit von zuerst Bibliothek, die sie implementiert. Das bedeutet, dass Sie die system -Versionen von _NSConcreteGlobalBlock und freunde finden, die nicht sind, die von der benutzerdefinierten ObjC-Laufzeit des Simulators initialisiert wurden.

Für (viele!) weitere Informationen zu dem Problem und um zu sehen, wie ich es aufgespürt habe, schaut euch den Thread an, den ich erstellt habe die Apple Entwicklerforen .

    
Jim Dovey 10.08.2011, 17:40
quelle