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];
}

69voto

kperryua Punkte 10424

Ja, Ihr zweiter Codeschnipsel ist absolut gültig.

Jedes Mal, wenn -autorelease an ein Objekt gesendet wird, wird es dem innersten Autorelease-Pool hinzugefügt. Wenn der Pool geleert ist, wird einfach -release an alle Objekte im Pool gesendet.

Autofreigabepools sind lediglich eine praktische Funktion, die es Ihnen ermöglicht, das Senden der Freigabe auf "später" zu verschieben. Dieses "später" kann an verschiedenen Stellen erfolgen, am häufigsten jedoch in Cocoa-GUI-Anwendungen am Ende des aktuellen Schleifenlaufs.

37voto

mmalc Punkte 8201

NSAutoreleasePool: Abfluss vs. Freigabe

Da die Funktion der drain y release Verwirrung zu stiften scheinen, wäre es vielleicht sinnvoll, dies hier zu klären (obwohl dies in die Dokumentation ...).

Streng genommen, aus der Perspektive des großen Ganzen drain ist pas gleichbedeutend mit release :

In einer Umgebung mit Referenzzählung, drain führt dieselben Operationen aus wie release Die beiden sind also in diesem Sinne gleichwertig. Zur Verdeutlichung: Das bedeutet, dass Sie pas einen Pool lecken, wenn Sie drain statt release .

In einer Umgebung, in der Müll gesammelt wird, release ist ein No-op. Sie hat also keine Wirkung. drain enthält dagegen einen Hinweis an den Collector, dass er "bei Bedarf sammeln" soll. In einer Umgebung, in der Müll gesammelt wird, ist daher die Verwendung von drain hilft dem System, die Sammelvorgänge auszugleichen.

17voto

Neovibrant Punkte 737

Wie bereits erwähnt, ist Ihr zweiter Codeschnipsel korrekt.

Ich möchte eine prägnantere Methode zur Verwendung des Autorelease-Pools vorschlagen, die in allen Umgebungen (Ref-Counting, GC, ARC) funktioniert und auch die Verwirrung um Abfluss und Freigabe vermeidet:

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

Im obigen Beispiel beachten Sie bitte die @autoreleasepool blockieren. Dies ist dokumentiert aquí .

7voto

kperryua Punkte 10424

Nein, Sie irren sich. Die Dokumentation besagt eindeutig, dass unter Nicht-GC -drain gleichbedeutend mit -release ist, d.h. der NSAutoreleasePool wird pas durchgesickert sein.

0voto

Gagan_iOS Punkte 3326

Was ich bei Apple gelesen habe: "Am Ende des Autorelease-Pool-Blocks wird Objekten, die innerhalb des Blocks eine Autorelease-Nachricht erhalten haben, eine Release-Nachricht gesendet - ein Objekt erhält eine Release-Nachricht für jedes Mal, wenn ihm innerhalb des Blocks eine Autorelease-Nachricht gesendet wurde."

https://developer.apple.com/library/mac/documentation/cocoa/conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html

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