Was ist EXC_BAD_ACCESS und wie kann ich es debuggen?

An irgendeinem Punkt stoßen Sie auf einen Absturz, der durch verursacht wird EXC_BAD_ACCESS. In diesem kurzen Tipp erfahren Sie, was EXC_BAD_ACCESS ist und was es verursacht. Ich werde Ihnen auch ein paar Tipps geben, um Fehler zu beheben, die durch EXC_BAD_ACCESS verursacht werden.

1. Was ist EXC_BAD_ACCESS??

Wenn Sie die zugrunde liegende Ursache von EXC_BAD_ACCESS verstanden haben, können Sie den kryptischen Namen besser verstehen. Es gibt eine einfache Erklärung und eine technischere Erklärung. Beginnen wir mit der einfachen Erklärung.

Einfach halten

Immer wenn Sie auf EXC_BAD_ACCESS stoßen, bedeutet dies, dass Sie eine Nachricht an ein Objekt senden, das bereits freigegeben wurde. Dies ist das häufigste Szenario, es gibt jedoch Ausnahmen, wie wir gleich besprechen werden.

Was es wirklich bedeutet

Die technische Erklärung ist etwas komplexer. In C und Objective-C beschäftigen Sie sich ständig mit Zeiger. Ein Zeiger ist nichts anderes als eine Variable, die die Speicheradresse einer anderen Variablen speichert. Wenn Sie eine Nachricht an ein Objekt senden, muss der Zeiger auf das Objekt zeigen, an das Sie die Nachricht senden dereferenziert. Das bedeutet, Sie nehmen die Speicheradresse, auf die der Zeiger zeigt, und greifen auf den Wert dieses Speicherblocks zu.

Wenn dieser Speicherblock nicht mehr für Ihre Anwendung zugeordnet ist oder anders ausgedrückt, wird dieser Speicherblock nicht für das verwendet, von dem Sie annehmen, dass er verwendet wird, und es ist nicht mehr möglich, auf diesen Speicherblock zuzugreifen. In diesem Fall sendet der Kernel eine Ausnahme (EXC), um anzuzeigen, dass Ihre Anwendung nicht auf diesen Speicherblock zugreifen kann (Schlechter Zugang).

Zusammenfassend bedeutet dies, wenn Sie EXC_BAD_ACCESS ausführen, dass Sie versuchen, eine Nachricht an einen Speicherblock zu senden, der diese Nachricht nicht ausführen kann.

In einigen Fällen wird EXC_BAD_ACCESS jedoch durch einen beschädigten Zeiger verursacht. Immer wenn Ihre Anwendung versucht, einen beschädigten Zeiger dereferenzieren zu lassen, wird vom Kernel eine Ausnahme ausgelöst.

2. Debuggen von EXC_BAD_ACCESS

Das Debuggen von EXC_BAD_ACCESS kann schwierig und frustrierend sein. Nun, da EXC_BAD_ACCESS kein Rätsel mehr für Sie ist, sollte es weniger abschreckend sein.

Das erste, was Sie verstehen müssen, ist, dass Ihre Anwendung nicht notwendigerweise abstürzt, sobald der Speicherblock für Ihre Anwendung nicht mehr zugänglich ist. Das macht es oft schwierig, EXC_BAD_ACCESS zu debuggen.

Dasselbe gilt für korrupte Zeiger. Ihre Anwendung stürzt nicht ab, weil ein Zeiger beschädigt wurde. Es stürzt auch nicht ab, wenn Sie einen beschädigten Zeiger in Ihrer Anwendung herumgeben. Wenn Ihre Anwendung versucht, den beschädigten Zeiger zu dereferenzieren, kann dies jedoch schief gehen.

Zombies

Während Zombies in den letzten Jahren an Popularität gewonnen haben, gibt es sie seit mehr als einem Jahrzehnt in Xcode. Der Name Zombie Das hört sich vielleicht etwas dramatisch an, aber es ist eigentlich ein toller Name für die Funktion, die uns beim Debuggen von EXC_BAD_ACCESS helfen wird. Lassen Sie mich erklären, wie es funktioniert.

In Xcode können Sie Zombie-Objekte aktivieren, dh freigegebene Objekte werden als Zombies aufbewahrt. Anders ausgedrückt, freigegebene Objekte werden zu Debugging-Zwecken am Leben gehalten. Es ist keine Magie involviert. Wenn Sie eine Nachricht an ein Zombie-Objekt senden, stürzt Ihre Anwendung dennoch als Ergebnis von EXC_BAD_ACCESS ab.

Warum ist das nützlich? Was das Debuggen von EXC_BAD_ACCESS schwierig macht, ist, dass Sie nicht wissen, auf welches Objekt Ihre Anwendung zugreifen wollte. Zombie-Objekte lösen dieses Problem in vielen Fällen. Durch das Aufrechterhalten freigegebener Objekte kann Xcode Ihnen mitteilen, auf welches Objekt Sie zugreifen wollten, wodurch die Suche nach dem Problem erheblich vereinfacht wird.

Die Aktivierung von Zombies in Xcode ist sehr einfach. Beachten Sie, dass sich dies je nach verwendeter Xcode-Version unterscheiden kann. Der folgende Ansatz gilt für Xcode 6 und 7. Klicken Sie oben links auf das aktive Schema und wählen Sie Schema bearbeiten.

Wählen Lauf auf der linken Seite und öffnen Sie die Diagnose Tab oben. Um Zombie-Objekte zu aktivieren, aktivieren Sie das Kontrollkästchen Aktivieren Sie Zombie-Objekte.

Wenn Sie nun auf EXC_BAD_ACCESS stoßen, können Sie anhand der Ausgabe in der Xcode-Konsole viel besser wissen, wo Sie Ihre Suche starten möchten. Sehen Sie sich die folgende Beispielausgabe an.

2015-08-12 06: 31: 55.501 Debug [2371: 1379247] - Die Nachricht [ChildViewController antwortetToSelector:], die an die freigegebene Instanz 0x17579780 gesendet wurde

Im obigen Beispiel teilt uns Xcode mit, dass eine Nachricht von antwortetToSelector: wurde zu einem Zombieobjekt geschickt. Das Zombie-Objekt ist jedoch keine Instanz von mehr ChildViewController Klasse. Der Speicherblock, der zuvor dem Speicher zugewiesen wurde ChildViewController Instanz wird für Ihre Anwendung nicht mehr zugeordnet. Dies sollte Ihnen eine ziemlich gute Vorstellung davon geben, was die Ursache des Problems ist.

Leider können Zombie-Objekte Ihren Tag nicht für jeden Absturz speichern, der durch EXC_BAD_ACCESS verursacht wird. Wenn Zombie-Objekte den Trick nicht schaffen, dann ist es Zeit für eine richtige Analyse.

Analysieren

Wenn Zombie-Objekte Ihr Problem nicht lösen, ist die Ursache möglicherweise weniger trivial. In diesem Fall müssen Sie sich den Code genauer ansehen, der ausgeführt wird, wenn Ihre Anwendung abstürzt. Dies kann umständlich und zeitraubend sein.

Damit Sie Probleme in Ihrer Codebasis finden können, können Sie Xcode bitten, Ihren Code zu analysieren, um problematische Bereiche zu finden. Beachten Sie, dass Xcode Ihr Projekt analysiert, das heißt, es zeigt jedes potenzielle Problem auf, auf das es stößt.

Um Xcode mitzuteilen, dass Sie Ihr Projekt analysieren möchten, wählen Sie Analysieren von Xcode's Produkt Menü oder drücken Sie Umschalt-Befehl-B. Es dauert einige Sekunden, bis Xcode läuft, aber wenn es fertig ist, sollten Sie eine Liste der Probleme im sehen Issue Navigator auf der Linken. Durch die Analyse gefundene Probleme werden blau hervorgehoben.

Wenn Sie auf ein Problem klicken, führt Xcode Sie zu dem Codeblock, der Ihre Aufmerksamkeit erfordert. Beachten Sie, dass Xcode nur einen Vorschlag macht. In einigen Fällen ist das Problem möglicherweise nicht relevant und muss nicht korrigiert werden.

Wenn Sie den Fehler, der EXC_BAD_ACCESS verursacht, nicht finden können, ist es wichtig, alle während der Analyse Ihres Projekts gefundenen Xcodes sorgfältig zu prüfen.

Fazit

EXC_BAD_ACCESS ist eine häufige Frustration bei Entwicklern, die der manuellen Speicherverwaltung innewohnt. Probleme im Zusammenhang mit der Speicherverwaltung sind seit der Einführung von ARC (Automatic Reference Counting) seltener geworden, aber keineswegs verschwunden.