Warum beendet Assert einfach ein Programm, das für das iPhone kompiliert wurde?

8

Ich debugge eine schwer Assert () 'ed iPhone App (Xcode, Objective-C ++ und Gerätesimulator). In einigen Fällen würde der Assert-Fehler die App einfach beenden, anstatt wie erwartet in den Debugger einzudringen.

Ich habe einen Workaround gemacht, indem ich meine eigene Art-Assertion implementiert habe:

%Vor%

(Flaum weggelassen), aber ich frage mich, ob jemand jemals diesem begegnet ist. Ich konnte kein Muster bestimmen, wann es bricht und wann es endet. Der Code ist nicht gewunden; Alles, was es tut, wird in Eventhandlern erledigt.

Warum passiert das und wie mache ich Vanille assert () verhalten sich wie ein bedingter Haltepunkt sollte es sein?

    
Seva Alekseyev 04.01.2010, 17:41
quelle

4 Antworten

15

Erstens, da Sie an einer iPhone-App arbeiten, sollten Sie NSAsssert () anstelle der Vanilla-BSD-Assert-Funktion verwenden.

z.B. NSAssert(the_object, @"NIL object encountered");

Das NSAssert-Makro wird eine Objective-C-Ausnahme ( NSInternalInconsistencyException ) ausgeben, wenn die Assertion fehlschlägt.

Da Ihr Ziel darin besteht, die Ausnahme zu unterbrechen, besteht der nächste Schritt darin, den Xcode-Debugger bei Objective-C-Ausnahmen zu unterbrechen. Dies ist wahrscheinlich eine gute Sache zu tun.

Klicken Sie im Fenster "Breakpoints" (Befehl "Run- & gt; Show- & gt; Breakpoints") auf die Stelle "Double-Click for Symbol", um das Symbol% ​​co_de%

einzugeben

Das letzte, was vorsichtig ist, ist, dass NSAsserts in einem Release-Build nicht kompilieren. Das bedeutet, dass Sie entweder bereit sein müssen, die Ausnahme in Ihrer Anwendung zu behandeln, oder Sie müssen ein eigenes Makro erstellen, das in Release-Builds kompiliert wird.

Hier ist das Makro, das ich verwende, um Behauptungen im Laufzeitcode zu kompilieren (beachte, dass ich dann HMAsert in meinem Code anstelle von NSAssert verwende):

%Vor%

Dies erfordert, dass ein DEBUG-Präprozessor-Makro definiert wird. So richten Sie das ein:

  1. Klicken Sie mit der rechten Maustaste auf Ihr Projekt in Xcode. Dies ist das oberste Element im linken Bereich, in dem Ihre Projektdateien aufgelistet sind
  2. Wählen Sie "Get Info" aus dem Kontextmenü, das erscheint.
  3. Gehen Sie zum Tab "Erstellen".
  4. Stellen Sie sicher, dass "Configuration" auf "Debug" eingestellt ist.
  5. Geben Sie DEBUG in das Feld neben "Preprocessor Macros" unter "GCC 4.2 - Preprocessing" ein.
Michael Taylor 05.01.2010 00:48
quelle
4

Wenn Sie im Breakpoint Navigator (⌘6) "Exception Breakpoint hinzufügen ..." hinzufügen, stoppt der Debugger bei NSAssrts Fehlern, sodass Sie sich den Stack ansehen und verstehen können, was schief gelaufen ist.

Sie sollten den Standard NSAsssert verwenden. Wenn Sie es richtig verwenden, müssen Sie nicht viel manuell erstellen - alles, was Mike erwähnt, ist ähnlich der standardmäßigen Implementierung von NSAssert.

Sie sollten die Release-Konfiguration mit NS_BLOCK_ASSERTIONS in Ihren vorkompilierten Headern ausführen (folgen Sie den Schritten von Mike), um Assertionen zu deaktivieren. Wenn Sie weitere Informationen darüber benötigen, warum Sie dies tun sollten, gehen Sie folgendermaßen vor: Ссылка

    
Ohad Kravchick 24.11.2010 02:52
quelle
0

In NSXsert 4 und Xcode 4 kann NSAssert eine variable Liste von Parametern enthalten. Dies kann nützlich sein, um einige Werte zusammen mit dem Assert zu protokollieren. Der Kompilierungs-Assert (siehe obige Antwort von Mike) könnte wie folgt definiert werden:

%Vor%

Außerdem gibt es nicht mehr den Menübefehl Run → Show → Breakpoints. Siehe diesen Beitrag , um Xcode 4 einzurichten, um zu brechen auf einem Assert wie oben definiert.

    
Amiramix 23.04.2012 13:50
quelle
0

Einmal sah ich ein anderes Verhalten als die assert () Aufrufe einmal. Es wurde dadurch verursacht, dass der Compiler verschiedene Makrodefinitionen an verschiedenen Stellen des Build-Prozesses aufnahm.

Sobald die Include-Pfade geglättet wurden, funktionierten alle gleich.

    
Walt Sellers 14.02.2013 07:57
quelle