2011-01-08 13 views
101

Ich würde gerne wissen, in welcher Situation haben Sie -retainCount bisher verwendet, und schließlich die Probleme, die bei der Verwendung auftreten können.Wann muss -halteCount verwendet werden?

Danke.

+5

sollten Sie ** niemals ** den '-retainCount' benutzen. – holex

+1

(Außer wenn Sie sollten. Es ist * sehr gelegentlich * nützlich, um zu verstehen, was vor sich geht, solange Sie wissen, dass es manchmal sehr irreführend sein kann. Und natürlich ist es überhaupt nicht erlaubt, ARC zu verwenden.) –

Antwort

231

Sie sollten niemals -retainCount verwenden, weil es Ihnen nie etwas Nützliches sagt. Die Implementierung der Foundation- und AppKit/UIKit-Frameworks ist undurchsichtig. Sie wissen nicht, was behalten wird, warum es beibehalten wird, wer es behält, wann es beibehalten wurde und so weiter.

Zum Beispiel:

  • Man sollte meinen, dass [NSNumber numberWithInt:1] hätte ein retainCount von 1. Es ist nicht. Es ist 2.
  • Sie würden denken, dass @"Foo" eine retainCount von 1 haben würde. Es tut es nicht. Es ist 1152921504606846975.
  • Sie würden denken, dass [NSString stringWithString:@"Foo"] eine retainCount von 1 haben würde. Es tut es nicht. Wieder ist es 1152921504606846975.

Grundsätzlich, da alles ein Objekt beibehalten kann (und damit verändern ihre retainCount), und da Sie die Quelle nicht der Code für die meisten, die eine Anwendung ausgeführt wird, retainCount eines Objekts ist bedeutungslos.

Wenn Sie herausfinden möchten, warum ein Objekt nicht freigegeben wird, verwenden Sie das Werkzeug "Leaks" in den Instrumenten. Wenn Sie herausfinden möchten, warum ein Objekt zu früh freigegeben wurde, verwenden Sie das Tool "Zombies" in "Instrumente".

Aber nicht -retainCount verwenden. Es ist eine wirklich wertlose Methode.

bearbeiten

Bitte jeder http://bugreport.apple.com und Wunsch gehen, die veraltet -retainCount. Je mehr Leute danach fragen, desto besser.

bearbeiten # 2

als Update hat [NSNumber numberWithInt:1] jetzt ein retainCount von 9223372036854775807. Wenn Ihr Code es erwartet hatte zu sein 2, hat der Code nun gebrochen.

+3

Danke @ Dave-Delong für Ihre Beispiele. – Moszi

+1

retainCount ist zur Zeit nützlich für Singletons (Nun ist die Frage, wie nützlich sind Singletons ...) '- (NSUInteger) retainCount {NSUIntegerMax zurückkehren;}.'. – Joe

+8

@Joe Sie können ein Singleton ohne überschreiben 'RetainCount' machen. –

50

NIEMALS!

Ernsthaft. Tu es einfach nicht.

Folgen Sie einfach die Memory Management Guidelines und erst freigeben, was Sie alloc, new oder copy (oder alles, was Sie retain auf ursprünglich genannt).

@bbum sagte es am besten here on SO, und in noch mehr Details auf his blog.

+2

warum? was sind die Gründe ? – Moszi

+7

Weil Sie denken, dass Sie die Erinnerung zählen, aber Sie werden es falsch machen. – Abizern

+0

@Abizern - und was ist mit der Singleton Situation in einer der anderen Antworten? – Moszi

3

Welche Probleme können Sie von der Verwendung bekommen? Es gibt nur die Retain-Anzahl des Objekts zurück. Ich habe es nie genannt und kann mir keinen Grund dafür vorstellen. Ich habe es in Singletons überschrieben, um sicherzustellen, dass sie nicht freigegeben werden.

+2

Es gibt keinen Grund, sie im Singletonfall zu überschreiben. Es gibt keine Codepfade in der Foundation/CoreFoundation, die 'retainCount' für die Speicherverwaltung verwenden. – bbum

+0

Gibt es keine Freigabe, um zu entscheiden, ob es dealloc aufrufen soll? – ughoavgfhw

+2

Nein; Die interne Implementierung von Retain/Release/Autorelease ist tief in CoreFoundation verwurzelt und ist wirklich nicht das, was Sie erwarten könnten. Greifen Sie die CoreFoundation-Quelle (es ist verfügbar) und schauen Sie sich um. – bbum

5

einen Blick auf die Dokumentation von Apple Nehmen Sie auf NSObject, ist es Ihre Frage ziemlich bedeckt: NSObject retainCount

Kurz gesagt, ist retainCount Sie wahrscheinlich nutzlos, wenn Sie Ihre eigenen Referenz Zählsystem implementiert haben (und ich kann fast garantieren, dass Sie nicht haben).

In den eigenen Worten von Apple ist retainCount "in der Debugging-Speicherverwaltungsprobleme in der Regel keinen Wert".

+0

Zunächst einmal vielen Dank für Ihre Antwort. Normalerweise reagiert die Bevölkerung auf diese Frage "NIE". (Siehe die Antworten). Eigentlich "kein Wert im Debuggen" bedeutet nicht "NIE". Also meine Frage ist - warum ist das starke Gefühl, es nicht zu benutzen (zum Beispiel in Singleton-Implementierung - eine der Antworten wieder)? – Moszi

+0

Ich denke, dass Sie mehr Informationen darüber geben müssten, wofür Sie es verwenden. Eine akzeptable Verwendung wäre, wie von Apple vorgeschlagen, das Überschreiben von retainCount, um ein eigenes Referenzzählsystem zu implementieren. Aber in der Praxis würden Sie das nie sehen (ich habe es sowieso nie). Die starke Reaktion kommt im Allgemeinen von der Tatsache, dass Apple selbst (in ihren Mail-Gruppen, den Docs, den Dev-Foren usw.) befürwortet hat, retainCount alleine zu lassen. – lxt

+1

@Moszi: Debuggen ist die einzige Situation, in der sich die meisten Leute vorstellen können, dass sie einen Wert hat. Wenn es dort also unzuverlässig ist, ist es nie nützlich. An was für andere Anwendungen denken Sie? – Chuck

3

Sie sollten sich keine Sorgen über Speicherlecks machen, bis Ihre App läuft und etwas Nützliches macht.

Sobald es ist, feuern Instrumente und verwenden Sie die App und sehen, ob Speicherlecks wirklich passieren. In den meisten Fällen haben Sie selbst ein Objekt erstellt (also besitzen Sie es) und vergessen, es nach dem Beenden freizugeben.

Versuchen Sie nicht, Ihren Code zu optimieren, während Sie ihn schreiben, Ihre Vermutungen darüber, was Speicher verlieren oder zu lange dauern kann, sind oft falsch, wenn Sie die App normalerweise verwenden.

Versuchen Sie, den richtigen Code zu schreiben, z. Wenn Sie ein Objekt mit alloc und so erstellen, stellen Sie sicher, dass Sie es ordnungsgemäß freigeben.

+0

Während das sind in der Regel gute Ratschläge :) - sie beantworten meine Frage nicht ... – Moszi

14

Automatisch freigegebene Objekte sind ein Fall, in dem die Überprüfung von -halteCount nicht informativ und möglicherweise irreführend ist. Die Retain-Anzahl sagt nichts darüber aus, wie oft eine Autoreelease für ein Objekt aufgerufen wurde und wie oft sie freigegeben wird, wenn der aktuelle Autorelease-Pool leer ist.

+1

Danke - das ist ein guter Punkt. Dies ist die erste Antwort, die tatsächlich einen Grund hat, warum nicht verwenden Sie retainCount, neben dem generischen "nicht". – Moszi

+1

@Moszi: Ihre Frage war "wann RetainCount zu verwenden?" - Wenn Sie diese Frage nicht stellen wollten, hätten Sie etwas anderes fragen sollen. – Chuck

+0

@chuck - eigentlich war ich daran interessiert, "wann ich es benutzen soll", aber es scheint, dass jede Antwort "nie" sein wird ... Aber - ich denke du hast Recht. Ich werde die Frage für ein paar Tage offen lassen, und wenn es keine andere Antwort gibt als nie, dann werde ich "nie" als Antwort akzeptieren. – Moszi

10

I do Finden Sie retentionCounts sehr nützlich, wenn sie mit 'Instruments' überprüft werden.

Verwenden Sie das Werkzeug "Zuweisungen", stellen Sie sicher, dass "Referenzzählungen aufzeichnen" aktiviert ist und Sie können in jedes Objekt gehen und dessen Verlauf von retainCount sehen.

Durch die Zuordnung von Alloc und Releases können Sie sich ein gutes Bild von dem machen, was vor sich geht, und oft die schwierigen Fälle lösen, in denen etwas nicht veröffentlicht wird.

Das hat mich nie im Stich gelassen - einschließlich Bugs in frühen Beta-Versionen von iOS zu finden.

0

Sie sollten es nie in Ihrem Code verwenden, aber es könnte auf jeden Fall helfen, wenn

Debuggen
0

niemals den -retainCount in Ihrem Code verwenden. Wenn Sie jedoch verwenden, werden Sie nie sehen, dass es Null zurückgibt. Denke darüber nach, warum. :-)

2

Natürlich sollten Sie niemals die retainCount-Methode in Ihrem Code verwenden, da die Bedeutung des Werts davon abhängt, wie viele Autoreleases auf das Objekt angewendet wurden, was Sie nicht vorhersagen können. Es ist jedoch sehr nützlich für das Debuggen - insbesondere, wenn Sie Speicherlecks in Code aufspüren, die Methoden von Appkit-Objekten außerhalb der Hauptereignisschleife aufrufen - und es sollte nicht veraltet sein.

In Ihrem Bemühen, Ihren Standpunkt zu betonen, haben Sie die unergründliche Natur des Wertes ernsthaft übertrieben. Es ist wahr, dass es nicht immer eine Referenzzahl ist. Es gibt einige spezielle Werte, die für Flags verwendet werden, z. B. um anzuzeigen, dass ein Objekt nie freigegeben werden soll. Eine Zahl wie 1152921504606846975 sieht sehr mysteriös aus, bis man sie in hex schreibt und 0xfffffffffffffff bekommt. Und 9223372036854775807 ist 0x7fffffffffffffff in hex. Und es ist wirklich nicht so überraschend, dass jemand solche Werte als Flags verwenden würde, da es fast 3000 Jahre dauern würde, um einen retainCount so hoch wie die größere Zahl zu erhalten, vorausgesetzt, Sie haben den retainCount 100.000.000 Mal pro Sekunde erhöht.

Verwandte Themen