Ermitteln, ob sich das Objekt in einem NSAutoreleasePool befindet

8

Ich würde gerne wissen, wie oft ein Objekt automatisch freigegeben wurde. Ich habe das Ziel c lange genug benutzt, dass es im Allgemeinen einfach ist, zu wissen, ob ein Objekt eine Autorelease erhalten hat oder nicht, aber ich sehe ständig Fragen, die sich mit Speicher befassen und Zählungen behalten. Irgendwann endet eine Antwort immer, "Sie können dem retainCount eines Objekts nicht vertrauen" - dem stimme ich zu, ABER wenn Sie bestimmen könnten, wie oft ein Objekt automatisch freigegeben wurde, dann könnten Sie tatsächlich vertrauen the retainCount, wenn Sie eine Kategorie wie folgt hinzugefügt haben:

%Vor%

Es würde immer noch eine Ausnahme für unveränderliche Typen geben, da diese normalerweise die Anzahl der Retains während einer Kopie erhöhen. Daher können Sie immer noch nicht auf retainCount vertrauen.

Was ich NICHT vorschlage

Ich suche diese Antwort nicht, um retainCount im Produktionscode zu verwenden. Ich kann dies jedoch als wertvoll für jemanden betrachten, der Probleme mit dem Arbeitsspeicher beseitigt.

Ich kann mir vorstellen, dass einige Leute diese Frage hassen werden, da Programmierer sich nicht darum kümmern sollten, wie oft ein Objekt automatisch freigegeben wurde. Bei der Codierung sollte es darum gehen, Allokierungen auszugleichen, zu behalten, zu kopieren, neu zu veröffentlichen, Ende der Geschichte. Der Sinn dahinter ist jedoch, Leuten zu helfen, die auf ihren Kopf schlagen. [NSObject retainCount] brennt eine Menge Leute, und eine Antwort auf diese Frage wäre ziemlich cool.

Ich bin mir sicher, dass es einen Weg gibt zu bestimmen, wie oft ein Objekt automatisch freigegeben wurde. Ich weiß einfach nicht was es ist, daher die Frage.

Siehe ähnliche Frage: Objekte in NSAutoreleasePool in objective-c .

Bearbeiten

Danke euch allen für eure Antworten. Vielleicht finden Sie das interessant = & gt; Ariel wies darauf hin, dass GNUStep Implementierung von Cocoa und speziell es ist NSAutoreleasePool hat diese Methode: + (NSUInteger) autoreleaseCountForObject: (id) anObject . Diese Methode ist langsam und gibt nur die Autorelease-Anzahl von NSAutoReleasePools im Anruferthread zurück. Trotzdem ... Es ist interessant, dass es da ist. Die Dokumentation zitiert, dass es wirklich nur zum Debuggen nützlich ist. Das war wirklich, was ich im Cocoa-Framework irgendwie finden (oder für möglich halten) wollte.

Ich stimme den Antworten zu, dass selbst wenn es möglich wäre, die Autorelease-Zählung zu erhalten, dass bessere Werkzeuge existieren (Zombies, Lecks, statischer Analysator).

    
Sam 22.09.2011, 14:53
quelle

4 Antworten

7

Zuerst müssten Sie mit mehreren Autorelease-Pools arbeiten und ein Objekt mehrmals automatisch wieder freigeben, möglicherweise in mehreren Pools.

Zweitens ist es nicht (nur) NSAutoreleasePool , das -retainCount untrustworthy macht. Das Problem ist, dass alle Arten von Objekten, sowohl Ihre als auch die von Apple, Dinge aus den verschiedensten Gründen behalten, die Ihnen am meisten unbekannt sind. Selbst bei der Autorelease haben Ihre Objekte oft nicht die von Ihnen erwartete Anzahl an Retains, weil hinter den Kulissen etwas beobachtet oder vorübergehend in ein Wörterbuch eingefügt wird.

Die besten Methoden, um Speicherprobleme zu beheben, sind das Leaks-Instrument, NSZombie und der statische Analysator.

    
andyvn22 22.09.2011, 15:13
quelle
5

Nein, es gibt keine öffentliche API, um festzustellen, ob ein Objekt automatisch freigegeben wurde.

Selbst wenn dies öffentlich verfügbar wäre, hätte Ihre -retainCountWithAutoRelease -Methode einige Probleme:

  • Ein Objekt kann mehrere Male im selben Autorelease-Pool platziert werden, sodass Sie eine Autorelease-Zählung für einen einzelnen Autorelease-Pool anstelle eines Flags benötigen, das angibt, ob ein Objekt automatisch freigegeben wurde;

  • Ein Objekt kann aufgrund von Multithreading in mehreren Autorelease-Pools platziert werden, sodass Sie eine Autorelease-Anzahl benötigen, die mehrere Autorelease-Pools umfasst;

  • Aufgrund von Multithreading müssen Sie Ihren Code mit der Cocoa-Behandlung von Retain-Counts und Autorelease-Pools synchronisieren, und die von Cocoa verwendete interne Sperre ist für Anwendungen nicht sichtbar.

user557219 22.09.2011 15:14
quelle
1

NSAutoreleasePool hat eine +(void)showPools Methode, die ich vorher völlig nicht bewusst war. Dies könnte nützlich sein. Siehe auch Gibt es eine Möglichkeit, einen NSAutoreleasePool zu inspizieren Objekte? . An diesem Thread, sagte KennyTM (in einem Kommentar):

  

Nun, da der Inhalt auf stderr gedruckt wird, können Sie das wieder öffnen   streamen und parsen, um alle Zeiger zu erhalten

Als Referenz habe ich den Klassen-Dump gegen das Foundation-Framework verwendet, um seine NSAutoreleasePool-Details zu sehen, und er hatte folgendes:

%Vor%

Ich habe dies als eine Antwort hinzugefügt, da es eher eine Antwort schien als näher auf die Frage, fragte ich.

    
Sam 23.09.2011 15:15
quelle
0

Klingt so, als müssten Sie -(id)autorelease; method als Aufgabe des Hinzufügens eines Objektes zu NSAutoreleasePool überschreiben.
Etwas wie das:

%Vor%

Sehen Sie sich auch diesen Link

an     
Ariel 22.09.2011 15:21
quelle