IMHO, welcher Weg ist "richtig" ist eine Frage der Präferenz. Ich stimme den Respondern nicht zu, die befürworten, autorelease
nicht zu verwenden, aber meine Präferenz ist, autorelease
zu verwenden, es sei denn, es gibt einen überwältigend zwingenden Grund nicht zu. Ich werde meine Gründe aufzählen und Sie können entscheiden, ob sie zu Ihrem Stil der Programmierung passen oder nicht.
Wie Chuck herausfand, gibt es eine semi-urbane Legende, dass es einen gewissen Overhead für die Verwendung von Autorelease-Pools gibt. Dies könnte nicht weiter von der Wahrheit entfernt sein, und das kommt von unzähligen Stunden mit Shark.app, um das letzte bisschen Leistung aus dem Code zu drücken. Der Versuch, dies zu optimieren, liegt im Bereich der "voreiligen Optimierung". Wenn und nur wenn, Shark.app Ihnen harte Daten gibt, dass dies ein Problem sein könnte, sollten Sie sogar in Betracht ziehen, darauf zu schauen.
Wie andere darauf hingewiesen haben, wird ein automatisch freigegebenes Objekt zu einem späteren Zeitpunkt "freigegeben". Das heißt, sie verweilen und nehmen das Gedächtnis auf, bis dieser "spätere Punkt" herumrollt. Für "die meisten" Fälle befindet sich dies am Ende eines Ereignisverarbeitungsdurchlaufs, bevor die Ausführungsschleife bis zum nächsten Ereignis ruht (Zeitgeber, Benutzer, der auf etwas klickt usw.).
Gelegentlich müssen Sie diese temporären Objekte eher früher als später entfernen. Beispielsweise müssen Sie eine riesige Datei mit mehreren Megabyte oder mehrere zehntausend Zeilen aus einer Datenbank verarbeiten. Wenn dies passiert, müssen Sie einen an einem gut gewählten Punkt, gefolgt von einem [pool release];
an der Unterseite platzieren. Dies geschieht fast immer in einer Art "Schleifen-Batch-Verarbeitung", so dass es normalerweise am Anfang und Ende einer kritischen Schleife liegt. Auch dies sollte evidenzbasiert und nicht auf Mutmaßungen basieren. In der ObjectAlloc von Instrument.app finden Sie diese Problemstellen.
Der Hauptgrund, warum ich autorelease
zu release
, bevorzugen allerdings, dass es viel einfacher ist, leckagefreie Programme zu schreiben. Kurz gesagt, wenn Sie den release
Weg gehen wählen, müssen Sie Garantie dass release
schließlich zu obj
gesendet wird, unter alle Umständen. Während dies scheint einfach zu sein, ist es tatsächlich überraschend schwer in der Praxis zu tun. Nehmen Sie sich beispielsweise zum Beispiel:
// array is an instance of NSMutableArray
MyClass *obj = [[MyClass alloc] init];
[array addObject:obj];
// Assume a few more lines of work....
[obj release];
Nun, da sich vorstellen, aus irgendeinem Grund, etwas, irgendwo verletzt subtil Ihre Annahme, dass array
wandelbar ist, vielleicht als Ergebnis eine Methode unter Verwendung der Ergebnisse zu verarbeiten, und die zurück Array mit den verarbeiteten Ergebnissen wurde als NSArray
erstellt.Wenn Sie an das unveränderliche NSArray
senden, wird eine Ausnahme ausgelöst, und Sie senden nie obj
seine release
Nachricht. Oder vielleicht etwas schief geht irgendwo zwischen wenn obj
waren alloc
d und die erforderlich Aufruf release
, wie Sie eine Bedingung überprüfen und return()
sofort versehentlich, weil es den Geist schlüpfte, dass dieser Anruf zu release
später muss stattfinden.
Sie haben gerade ein Objekt durchgesickert. Und wahrscheinlich haben Sie sich mehrere Tage damit beschäftigt, herauszufinden, wo und warum Sie es verlieren. Aus Erfahrung werden Sie viele Stunden damit verbringen, diesen Code oben zu betrachten, in der Überzeugung, dass es nicht die Quelle des Lecks sein kann, weil Sie sehr deutlich obj
eine release
senden. Dann, nach einigen Tagen, werden Sie erleben, was man nur als religiöse Epiphanie bezeichnen kann, wenn Sie für die Ursache des Problems erleuchtet sind.
Betrachten Sie den autorelease
Fall:
// array is an instance of NSMutableArray
MyClass *obj = [[[MyClass alloc] init] autorelease];
[array addObject:obj];
// Assume a few more lines of work....
Jetzt ist es nicht mehr wichtig, was passiert, weil es praktisch unmöglich ist, obj
versehentlich auslaufen, auch unter extrem ungewöhnlichen oder außergewöhnlichen Fällen Ecke.
Wenn Sie möchten, dass Ihr Code absolut sicher ist, wird dringend empfohlen, die Autorelease zu verwenden: Siehe http://stackoverflow.com/questions/1147785/use-autorelease-before-adding-objects-to-a-collection/1149040#1149040 – Casebash