Ja und nein. Sie würden am Ende den Stringspeicher freigeben, aber das NSAutoreleasePool-Objekt in den Speicher "lecken", indem Sie drain statt release verwenden, wenn Sie dies in einer Garbage-Collected-Umgebung (nicht speicherverwaltet) ausführen. Dieses "Leck" macht die Instanz von NSAutoreleasePool einfach "unerreichbar" wie jedes andere Objekt ohne starke Zeiger unter GC, und das Objekt würde beim nächsten GC-Lauf aufgeräumt werden, was sehr wohl direkt nach dem Aufruf von -drain
:
Ablauf
Löst in einer Garbage-Collection-Umgebung die Garbage-Collection aus, wenn der seit der letzten Collection zugewiesene Speicher größer ist als der aktuelle Schwellenwert; andernfalls verhält er sich wie Release. ... In einer Garbage-Collected-Umgebung ruft diese Methode letztendlich objc_collect_if_needed
.
Ansonsten ist es ähnlich wie bei der -release
verhält sich unter Nicht-GC, ja. Wie andere bereits festgestellt haben, -release
ist ein No-op unter GC, also ist der einzige Weg, um sicherzustellen, dass der Pool unter GC richtig funktioniert, durch -drain
und -drain
unter Nicht-GC funktioniert genau wie -release
unter Nicht-GC, und kommuniziert seine Funktionalität wohl auch klarer.
Ich sollte darauf hinweisen, dass Ihre Aussage "alles, was mit new, alloc oder init aufgerufen wird" nicht "init" enthalten sollte (sondern "copy"), da "init" keinen Speicher alloziert, sondern nur das Objekt einrichtet (wie ein Konstruktor). Wenn Sie ein zugewiesenes Objekt erhalten und Ihre Funktion nur init als solches aufruft, würden Sie es nicht freigeben:
- (void)func:(NSObject*)allocd_but_not_init
{
[allocd_but_not_init init];
}
Das verbraucht nicht mehr Speicher als der, mit dem Sie bereits begonnen haben (vorausgesetzt, init instanziert keine Objekte, aber für die sind Sie sowieso nicht verantwortlich).