Ich würde gerne wissen, in welcher Situation Sie -retainCount
bisher gearbeitet haben und welche Probleme bei der Verwendung auftreten können.
Vielen Dank.
Ich würde gerne wissen, in welcher Situation Sie -retainCount
bisher gearbeitet haben und welche Probleme bei der Verwendung auftreten können.
Vielen Dank.
Antworten:
Sie sollten niemals verwenden -retainCount
, da es Ihnen niemals etwas Nützliches sagt. Die Implementierung der Foundation- und AppKit / UIKit-Frameworks ist undurchsichtig. Sie wissen nicht, was aufbewahrt wird, warum es aufbewahrt wird, wer es aufbewahrt, wann es aufbewahrt wurde und so weiter.
Beispielsweise:
[NSNumber numberWithInt:1]
das hätte eine retainCount
von 1. Das tut es nicht. Es ist 2.@"Foo"
das hätte eine retainCount
von 1. Das tut es nicht. Es ist 1152921504606846975.[NSString stringWithString:@"Foo"]
das hätte eine retainCount
von 1. Das tut es nicht. Wieder ist es 1152921504606846975.Grundsätzlich ist die Bedeutung retainCount
eines Objekts retainCount
bedeutungslos , da alles ein Objekt behalten (und daher ändern ) kann und Sie nicht über die Quelle für den größten Teil des Codes verfügen, mit dem eine Anwendung ausgeführt wird.
Wenn Sie herausfinden möchten, warum ein Objekt nicht freigegeben wird, verwenden Sie das Werkzeug "Lecks" in "Instrumente". Wenn Sie herausfinden möchten, warum ein Objekt zu früh freigegeben wurde, verwenden Sie das Zombies-Tool in Instruments.
Aber nicht benutzen -retainCount
. Es ist eine wirklich wertlose Methode.
bearbeiten
Bitte gehen Sie zu http://bugreport.apple.com und fordern Sie dies an-retainCount
dies veraltet ist. Je mehr Leute danach fragen, desto besser.
bearbeiten # 2
Als Update hat [NSNumber numberWithInt:1]
jetzt eine retainCount
von 9223372036854775807. Wenn Ihr Code 2 erwartet hat, ist Ihr Code jetzt defekt.
- (NSUInteger)retainCount{return NSUIntegerMax;}
.
retainCount
.
Ernsthaft. Tu es einfach nicht.
Folgen Sie einfach dem Management - Richtlinien - Speicher und nur freigeben , was Sie alloc
, new
oder copy
(oder alles , was Sie genannt retain
auf ursprünglich).
@bbum sagte es am besten hier auf SO und noch detaillierter auf seinem Blog .
-retainCount
können, (mit viel mehr Details) von Instruments und seinen Tools abgerufen werden.
retain
, retain
, retain
, autorelease,
Autorelease, autorelease
könnte ein perfekt gültiges Ergebnis der Übergabe eines Objekts durch das UIKit API sein, zum Beispiel.
Autorelease-Objekte sind ein Fall, in dem die Überprüfung von -retainCount nicht aussagekräftig und möglicherweise irreführend ist. Die Aufbewahrungsanzahl sagt nichts darüber aus, wie oft -autorelease für ein Objekt aufgerufen wurde und wie oft es freigegeben wird, wenn der aktuelle Autorelease-Pool leer wird.
Das tue ich finde RetainCounts sehr nützlich, wenn mit 'Instruments' überprüfe.
Stellen Sie mit dem Tool "Zuordnungen" sicher, dass "Referenzzähler aufzeichnen" aktiviert ist und Sie in jedes Objekt gehen und dessen RetainCount-Verlauf anzeigen können.
Durch das Koppeln von Zuordnungen und Freigaben erhalten Sie ein gutes Bild davon, was gerade passiert, und können häufig die schwierigen Fälle lösen, in denen etwas nicht freigegeben wird.
Dies hat mich nie im Stich gelassen - einschließlich der Suche nach Fehlern in frühen Beta-Versionen von iOS.
Schauen Sie sich die Apple-Dokumentation zu NSObject an, sie deckt Ihre Frage ziemlich genau ab: NSObject RetainCount
Kurz gesagt, RetainCount ist für Sie wahrscheinlich nutzlos, es sei denn, Sie haben Ihr eigenes Referenzzählsystem implementiert (und ich kann fast garantieren, dass Sie dies nicht haben).
Nach Apples eigenen Worten ist RetainCount "normalerweise wertlos beim Debuggen von Speicherverwaltungsproblemen".
Natürlich sollten Sie niemals die RetainCount-Methode in Ihrem Code verwenden, da die Bedeutung ihres Werts davon abhängt, wie viele Autoreleases auf das Objekt angewendet wurden und was Sie nicht vorhersagen können. Es ist jedoch sehr nützlich für das Debuggen - insbesondere, wenn Sie Speicherlecks in Code suchen, der Methoden von Appkit-Objekten außerhalb der Hauptereignisschleife aufruft - und sollte nicht veraltet sein.
In Ihrem Bestreben, Ihren Standpunkt zu verdeutlichen, haben Sie die Undurchschaubarkeit des Wertes ernsthaft überbewertet. Es ist wahr, dass es nicht immer ein Referenzzähler ist. Es gibt einige spezielle Werte, die für Flags verwendet werden, um beispielsweise anzugeben, dass ein Objekt niemals freigegeben werden sollte. Eine Zahl wie 1152921504606846975 sieht sehr mysteriös aus, bis Sie sie hexadezimal schreiben und 0xfffffffffffffff erhalten. Und 9223372036854775807 ist 0x7fffffffffffffff in hex. Und es ist wirklich nicht so überraschend, dass sich jemand dafür entscheidet, Werte wie diese als Flags zu verwenden, da es fast 3000 Jahre dauern würde, bis ein RetainCount so hoch wie die größere Zahl ist, vorausgesetzt, Sie haben den RetainCount 100.000.000 Mal pro Sekunde erhöht.
Welche Probleme können Sie mit der Verwendung bekommen? Es wird lediglich die Anzahl der beibehaltenen Objekte zurückgegeben. Ich habe es nie angerufen und kann mir keinen Grund vorstellen, warum ich es tun würde. Ich habe es in Singletons überschrieben, um sicherzustellen, dass sie nicht freigegeben werden.
retainCount
für die Speicherverwaltung verwendet werden.
Sie sollten sich keine Sorgen über Speicherverluste machen, bis Ihre App betriebsbereit ist und etwas Nützliches tut.
Sobald dies der Fall ist, starten Sie Instruments und verwenden Sie die App, um festzustellen, ob tatsächlich Speicherlecks auftreten. In den meisten Fällen haben Sie ein Objekt selbst erstellt (also besitzen Sie es) und vergessen, es freizugeben, nachdem Sie fertig waren.
Versuchen Sie nicht, Ihren Code zu optimieren, während Sie ihn schreiben. Ihre Vermutungen darüber, was möglicherweise Speicherverlust verursacht oder zu lange dauert, sind oft falsch, wenn Sie die App tatsächlich normal verwenden.
Versuchen Sie, korrekten Code zu schreiben, z. B. wenn Sie ein Objekt mit alloc und dergleichen erstellen, und stellen Sie dann sicher, dass Sie es ordnungsgemäß freigeben.
-retainCount
.