Ok, hier ist der Deal, ich hasse es, Fragen zu meinem Debugging und Abstürzen zu stellen. Weil ich sie normalerweise selbst erledige, aber ich kann mich einfach nicht darum kümmern , selbst nachdem ich bereits mehrere Fragen gesehen habe .
Ok, hier ist das Problem. Ich finde, dass meine App mit diesem Stack-Trace zufällig ein- und ausgeschaltet wird:
*** -[ViewController respondsToSelector:]: message sent to deallocated instance 0x1e5d2ef0
Wo ViewController
kann variieren, manchmal hat der Ort, an dem mein Code abstürzt, KEINE Relevanz für diesen bestimmten ViewController
und besitzt oder nennt ihn nicht.
Um diese Konsolenverfolgung zu erhalten, habe ich Zombies aktiviert, andernfalls würde ich überhaupt keinen Konsolendruck erhalten, sondern nur:, objc_msgSend
was ich weiß, bedeutet, dass ich etwas verschicke, das veröffentlicht wird. Aber ich kann nicht finden, wo das ist ... Ich stecke wirklich fest! Normalerweise debugge ich immer meine Abstürze, also bin ich wirklich festgefahren.
Auch dies stürzt an verschiedenen Orten zu unterschiedlichen Zeiten ein und aus. Und der Ort, an dem es abstürzt, hat fast keine Relevanz für die ViewController
. Und ich finde das sehr verwirrend.
Benötigen Sie einen meiner Codes? Ich habe viele Dateien und da es an verschiedenen Orten abstürzt, wird das Verteilen meines Codes ein Chaos sein!
Ich habe ohne Glück versucht, symbolische Haltepunkte hinzuzufügen, und Zombies ist in der Instruments-Anwendung für iOS nicht verfügbar. Ich kann meine App nicht auf dem Simulator ausführen, da er nicht unterstützende Architektur-Frameworks enthält.
Vielen Dank an alle ...
quelle
Antworten:
Verwenden Sie Instrumente , um freigegebene Instanzfehler aufzuspüren. Profilieren Sie Ihre Anwendung ( Cmd ⌘+ I) und wählen Sie Zombies- Vorlage. Versuchen Sie nach dem Ausführen Ihrer Anwendung, sie zum Absturz zu bringen. Sie sollten so etwas bekommen:
Klicken Sie auf den Pfeil neben der Adresse im Popover, um das Objekt anzuzeigen, das nach der Freigabe aufgerufen wurde.
Sie sollten jetzt sehen, dass jeder geänderte Aufruf die Anzahl dieses Objekts beibehält. Dies kann daran liegen, dass Nachrichten direkt gespeichert / freigegeben sowie Autorelease-Pools geleert oder in NSArrays eingefügt werden.
In der RefCt- Spalte wird RetainCount angezeigt, nachdem die Aktion aufgerufen wurde, und Responsible Caller zeigt den Klassennamen und die Methode an, in der sie ausgeführt wurde. Wenn Sie auf eine Aufbewahrung / Freigabe doppelklicken, zeigen die Instrumente Ihnen die Codezeile an, in der dies ausgeführt wurde (Wenn dies nicht funktioniert, können Sie den Anruf überprüfen, indem Sie ihn auswählen und sein Gegenstück im Bereich " Erweiterte Details" auswählen ):
Auf diese Weise können Sie den gesamten RetainCount- Lebenszyklus eines Objekts untersuchen und Ihr Problem wahrscheinlich sofort feststellen. Alles, was Sie tun müssen, ist, fehlende Aufbewahrung für die neueste Version zu finden .
quelle
release
. Das Problem ist jedes unausgeglichenerelease
. Ich kann auch einfach ein Fehler beiretain
etwas sein, auf das Sie einen Zeiger behalten und auf das Sie später verweisen.hatte ein ähnliches Problem. In meinem Fall musste ein viewController Navigationscontroller-Ereignisse abrufen, sodass er als Navigationscontroller-Delegat registriert wurde:
Der Absturz tritt auf, wenn dieser Controller freigegeben wurde, aber immer noch der Delegat für den View-Controller war. Das Hinzufügen dieses Codes in dealloc hatte keine Auswirkung:
Da zum Zeitpunkt des Aufrufs von dealloc der Ansichts-Controller bereits aus der Ansichtshierarchie entfernt wurde, ist self.navigationController gleich Null, sodass der Vergleich garantiert fehlschlägt! :-(
Die Lösung bestand darin, diesen Code hinzuzufügen, um zu erkennen, dass der VC die Ansichtshierarchie verlässt, bevor er dies tatsächlich tut. Es verwendet eine in iOS 5 eingeführte Methode, um zu bestimmen, wann die Ansicht eingeblendet und nicht verschoben wird
Keine Abstürze mehr!
quelle
Für alle, die es nicht lösen können, sind hier einige andere Techniken:
https://stackoverflow.com/a/12264647/539149
https://stackoverflow.com/a/5698635/539149
https://stackoverflow.com/a/9359792/539149
https://stackoverflow.com/a/15270549/539149
https://stackoverflow.com/a/12098735/539149
Sie können Instrumente in Xcode 5 ausführen, indem Sie auf das Projekt-Popup-> Schema bearbeiten ... Profil -> Instrument klicken und Zuordnungen oder Lecks auswählen, dann Ihre App profilieren, Instrumente stoppen, auf die Info-Schaltfläche unter Zuordnungen klicken und "NSZombie-Erkennung aktivieren". .
Für die Nachrichten, die direkt aus dem com.apple.main-Thread stammen, wird dies jedoch wahrscheinlich nichts verraten.
Ich schlug über zwei Stunden lang mit dem Kopf darauf und die Antwort stellte sich als Überveröffentlichung heraus, die ich entdeckte, indem ich eine Kopie meines Projekts mit brutaler Gewalt auskommentierte, bis ich den Schuldigen fand:
Das Problem ist, dass Release die Variable nicht auf NULL setzt.
Das bedeutet, dass das Setzen auf NULL-Aufrufe erneut freigegeben wird, der Refcount dekrementiert und der Speicher sofort freigegeben wird, bis später die Variablen, die auf viewController verweisen, damit fertig sind.
Aktivieren Sie also entweder ARC oder stellen Sie sicher, dass Ihr Projekt konsistent Release oder NULL verwendet, jedoch nicht beide. Ich bevorzuge die Verwendung von NULL, da es dann keine Möglichkeit gibt, auf einen Zombie zu verweisen, aber es schwieriger macht, herauszufinden, wo Objekte freigegeben werden.
quelle
Ich hatte gestern das gleiche Problem in iOS getroffen. Ich habe IAP in der Unteransicht "Info" der App erstellt und Transaction Observer in viewDidLoad "Info" hinzugefügt. Beim ersten Kauf kein Problem, aber nachdem ich zum Hauptfenster zurückgekehrt bin und die Unteransicht zum erneuten Kauf eingegeben habe, ist das Problem "Nachricht an freigegebene Instanz gesendet" aufgetreten und die App ist abgestürzt.
Nachdem ich Transaction Observer im Dealloc entfernt habe, ist das Problem behoben.
quelle
zombie
Objekt für InApp-Käufe erhalten. Nach vielen Stunden des Grabens fand ich diesen ... Ein großes Dankeschön Mann.Ich hatte ein sehr ähnliches Problem und stellte fest, dass es an den eingestellten Navigationscontroller-Delegierten lag.
Das Folgende löste mein Problem,
quelle
Hatte das gleiche Problem in OS X.
Um dies zu lösen, reicht nicht genug
- (void)dealloc
Methode aus, wie @SoftwareEvolved bereits sagte. Ist aber leider- (void)viewWillDisappear
nur ab Version 10.10 verfügbar.Ich habe eine benutzerdefinierte Methode in meiner NSViewController-Unterklasse eingeführt, in der alle zombiegefährdenden Verweise auf Null gesetzt wurden. In meinem Fall waren das
NSTableView
Eigenschaften (delegate
unddataSource
).Das ist alles. Jedes Mal, wenn ich die Ansicht aus der Übersicht entfernen möchte, muss diese Methode aufgerufen werden.
quelle
Ich hatte das gleiche Problem. Es war schwierig zu finden, welcher Delegat das Problem verursacht, da es keine Zeilen- oder Code-Anweisung anzeigt. Ich habe es also versucht. Vielleicht wird es für Sie hilfreich.
quelle