2009-06-01 2 views
0

Ich habe ausfindig gemacht, warum NSObject Verweise, während explizit veröffentlicht werden, immer noch in ObjectAlloc angezeigt werden. Tatsächlich habe ich NSObject auf eine Basis-Shell reduziert, mit einem [[myObject alloc] init] unmittelbar gefolgt von einem [myObject release], und es sieht nicht so aus, als würde es in ObjectAlloc veröffentlicht werden. Dies ist ein großes Problem mit einer NavigationController-App, die mehrere View-Controller verschiebt/öffnet, da die zuletzt geöffneten View-Controller aufgrund dieser nicht veröffentlichten NSObject-Referenzen nicht freigegeben werden. Hmmmmmm.NSObject Release ... Immer noch in ObjectAlloc

Ich könnte meinen Code hier oben, und habe eine Reihe von "hast du, dass nie irgendwo hinkommen." Autorelease-Pools, blah blah.

Also, schauen wir uns die Probe 'SeismicXML' Beispiel App von Apple an ... feuern Sie es in ObjectAlloc/Leaks. Sehr einfach in getEarthquakeData:

XMLReader *streamingParser = [[XMLReader alloc] init]; 
[streamingParser parseXMLFileAtURL:[NSURL URLWithString:feedURLString] parseError:&parseError]; 
[streamingParser release];   

ich eine Tonne Müll rumliegen sehen in ObjectAlloc von XMLReader, obwohl es freigegeben wird. Ich wette, wenn wir einen 'refresh' Knopf in dieser App setzen, um 'getEarthquakeData' erneut aufzurufen, würden wir die App innerhalb von 5 Aktualisierungen zum Absturz bringen.

Irgendwelche Gedanken?

+0

Haben Sie versucht, am Telefon oder nur den Simulator? Was ist das eigentliche Problem, das Sie 101 Ausgänge verursacht? –

Antwort

2

Ich denke, Sie sind verwirrt über das ObjectAlloc-Instrument, das alle Objektzuordnungen für die Lebensdauer Ihrer Anwendung zeigen wird. Es wird hauptsächlich verwendet, um die Speichernutzung im Zeitverlauf zu verfolgen.

Das Instrument, das ich denke, dass Sie wollen, ist das, das Leaks genannt wird, das Ihnen zeigt, welche Erinnerung durch keinen Bezug darauf geleckt wird. Das sind Zeiger auf Objekte, die nicht freigegeben werden, bevor sie neu zugewiesen werden.

1

Möglicherweise befindet sich ein Autorelease-Pool, der das Objekt festhält. Wenn Sie viele automatisch freigegebene Objekte erstellen, ohne sie aus dem Pool zu entfernen, erhalten Sie Lecks, bis Sie mit dem Autorelease-Pool zur äußeren Schleife zurückkehren.

So funktioniert Autorelease-Pools: In der Hauptschleife gibt es einen Autorelease-Pool. Alles Autoreleased geht dorthin. Am Ende jeder Schleifeniteration werden alle Objekte im Pool freigegeben. Wenn Sie Objekte irgendwo in einer anderen Schleife zuweisen, werden sie erst freigegeben, wenn Sie zur Hauptschleife zurückkehren. Es sei denn natürlich, Sie erstellen Ihren eigenen Autorelease-Pool nur für die Schleife.

Ein anderes Problem könnte sein, dass Ihr Objekt niemals freigegeben wird. Wenn Sie eine Ausnahme zwischen + alloc und -release erhalten, erhalten Sie ein Leck. Eine Möglichkeit, dies zu beheben, ist stattdessen zu verwenden:

[[[XMLReader alloc] init] autorelease] 

Schließlich könnten Sie hier mit Garbage Collection arbeiten. Ich weiß nicht genug über das GC-System, um Ihnen zu sagen, welches Verhalten Sie erwarten sollten.

+0

Einverstanden. Lesen Sie die Release-Dokumente. Dies ist ein akzeptables Verhalten. Haben Sie das Experiment sowohl am Telefon als auch am Simulator ausprobiert? –

+0

Ich habe, und verwende auch die UICatalog-Beispielanwendung, um ObjectAlloc (in Leaks) zu betonen. Mit dieser App feuern Sie jede Seite außer "web" an und beobachten Sie, wie der Speicher weiter wächst ... und rufen Sie dann den Web View Controller und kaboom auf! Der Kaboom-Teil ist NICHT mit Lecks reproduzierbar, die mit dem Simulator laufen, obwohl sich der Speicher bis zu einem hohen Wasserpunkt anhäuft und sich zu stabilisieren scheint. Warum hat das ImageView in UICatalog zum Beispiel noch aktive Referenzen, die nach dem Poppen herumliegen? Keine Autorelease verwendet. – Steve