Das primäre Speicherproblem, dessen Sie sich noch bewusst sein müssen, ist das Beibehalten von Zyklen. Dies tritt auf, wenn ein Objekt einen starken Zeiger auf ein anderes hat, das Zielobjekt jedoch einen starken Zeiger auf das Original hat. Selbst wenn alle anderen Verweise auf diese Objekte entfernt werden, bleiben sie aneinander hängen und werden nicht freigegeben. Dies kann auch indirekt durch eine Kette von Objekten geschehen, bei denen das letzte in der Kette möglicherweise auf ein früheres Objekt verweist.
Es ist aus diesem Grund , dass die __unsafe_unretained
und __weak
Eigentum - Qualifikation bestehen. Ersteres behält kein Objekt bei, auf das es zeigt, lässt jedoch die Möglichkeit offen, dass dieses Objekt verschwindet und auf ein schlechtes Gedächtnis verweist, während letzteres das Objekt nicht beibehält und sich automatisch auf Null setzt, wenn sein Ziel freigegeben wird. Von den beiden __weak
wird im Allgemeinen auf Plattformen bevorzugt, die dies unterstützen.
Sie würden diese Qualifikationsmerkmale beispielsweise für Delegaten verwenden, bei denen das Objekt seinen Delegaten nicht behalten und möglicherweise zu einem Zyklus führen soll.
Ein weiteres wichtiges Problem im Zusammenhang mit dem Speicher ist die Behandlung von Core Foundation-Objekten und des zugewiesenen Speichers malloc()
für Typen wie char*
. ARC verwaltet diese Typen nicht, sondern nur Objective-C-Objekte. Sie müssen sich also weiterhin selbst mit ihnen befassen. Core Foundation-Typen können besonders schwierig sein, da sie manchmal mit passenden Objective-C-Objekten überbrückt werden müssen und umgekehrt. Dies bedeutet, dass die Steuerung von ARC hin und her übertragen werden muss, wenn zwischen CF-Typen und Objective-C eine Brücke geschlagen wird. Einige Schlüsselwörter im Zusammenhang mit dieser Überbrückung wurden hinzugefügt, und Mike Ash hat in seiner langwierigen ARC- Beschreibung eine hervorragende Beschreibung verschiedener Überbrückungsfälle .
Darüber hinaus gibt es einige andere weniger häufige, aber immer noch potenziell problematische Fälle, auf die in der veröffentlichten Spezifikation ausführlich eingegangen wird.
Ein Großteil des neuen Verhaltens, das darauf basiert, Objekte so lange zu behalten, wie es einen starken Zeiger auf sie gibt, ist der Speicherbereinigung auf dem Mac sehr ähnlich. Die technischen Grundlagen sind jedoch sehr unterschiedlich. Anstatt einen Garbage Collector-Prozess zu haben, der in regelmäßigen Abständen ausgeführt wird, um Objekte zu bereinigen, auf die nicht mehr verwiesen wird, basiert diese Art der Speicherverwaltung auf den strengen Aufbewahrungs- / Freigaberegeln, die wir alle in Objective-C einhalten müssen.
ARC übernimmt einfach die sich wiederholenden Speicherverwaltungsaufgaben, die wir seit Jahren ausführen müssen, und verlagert sie an den Compiler, damit wir uns nie wieder um sie kümmern müssen. Auf diese Weise haben Sie keine Probleme mit dem Anhalten oder Sägezahnspeicherprofilen, die auf mit Müll gesammelten Plattformen auftreten. Ich habe beide in meinen Mac-Anwendungen mit Müllsammlung erlebt und bin gespannt, wie sie sich unter ARC verhalten.
Weitere Informationen zur Garbage Collection im Vergleich zu ARC finden Sie in dieser sehr interessanten Antwort von Chris Lattner auf der Objective-C-Mailingliste , in der er viele Vorteile von ARC gegenüber der Objective-C 2.0-Garbage Collection auflistet. Ich bin auf einige der von ihm beschriebenen GC-Probleme gestoßen.
ARC hilft Ihnen nicht mit Nicht-ObjC-Speicher, zum Beispiel, wenn Sie
malloc()
etwas haben, brauchen Sie es immer nochfree()
.ARC kann getäuscht werden,
performSelector:
wenn der Compiler nicht herausfinden kann, was der Selektor ist (der Compiler generiert eine Warnung dazu).ARC generiert auch Code gemäß den ObjC-Namenskonventionen. Wenn Sie also ARC- und MRC-Code mischen, können Sie überraschende Ergebnisse erzielen, wenn der MRC-Code nicht das tut, was der Compiler für die Namen vielversprechend hält.
quelle
In meiner Anwendung sind aufgrund der folgenden 4 Probleme Speicherverluste aufgetreten:
Zum Glück bin ich auf folgenden Blog-Beitrag gestoßen und konnte ihn korrigieren: http://www.reigndesign.com/blog/debugging-retain-cycles-in-objective-c-four-likely-culprits/
quelle
ARC verwaltet auch keine CoreFoundation-Typen. Sie können sie "überbrücken" (mit
CFBridgingRelease()
), aber nur, wenn Sie sie als Objective-C / Cocoa-Objekt verwenden möchten. Beachten Sie, dass CFBridgingRelease die Anzahl der CoreFoundation-Retains nur um 1 verringert und in den ARC von Objective-C verschiebt.quelle
Xcode 9 bietet ein großartiges Tool, um solche Probleme zu finden. Es heißt: " Debug Memory Graph ". Wenn Sie es verwenden, können Sie Ihr durchgesickertes Objekt nach Klassentyp finden und klar sehen, wer einen starken Bezug dazu hat, indem Sie es von dort freigeben, um Ihr Problem zu lösen. Es erkennt auch Speicherzyklen.
Weitere Informationen zur Verwendung finden Sie hier
quelle