96 Stimmen

Wie funktioniert der NSAutoreleasePool-Autorelease-Pool?

So wie ich es verstehe, wird alles, was mit einer zuweisen , neu , oder kopieren. muss manuell ausgelöst werden. Zum Beispiel:

int main(void) {
    NSString *string;
    string = [[NSString alloc] init];
    /* use the string */
    [string release];
}

Meine Frage ist jedoch, ob dies nicht genauso gültig wäre:

int main(void) {
    NSAutoreleasePool *pool;
    pool = [[NSAutoreleasePool alloc] init];
    NSString *string;
    string = [[[NSString alloc] init] autorelease];
    /* use the string */
    [pool drain];
}

0voto

Hardik Mamtora Punkte 1572

Das Senden von "Autorelease" anstelle von "Release" an ein Objekt verlängert die Lebensdauer dieses Objekts mindestens so lange, bis der Pool selbst geleert wird (es kann länger dauern, wenn das Objekt anschließend behalten wird). Ein Objekt kann mehrmals in denselben Pool aufgenommen werden. In diesem Fall erhält es jedes Mal eine Release-Nachricht, wenn es in den Pool aufgenommen wurde.

-2voto

Loren Segal Punkte 3258

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).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X