2010-11-19 9 views
2

Ich habe über Autoreleasepool gelesen, aber es gibt einen Punkt, der ein bisschen unklar für mich ist. Ich habe einige Funktionalität mit Threads, die separate Speicherverwaltung mit Autorespulepool benötigt.iPhone Autoreleasepool und Allokationen

Im folgenden Beispiel korrekt ist

-(void) doSomething { 

    NSAutorelease *pool = [[NSAutorelasepool alloc] init]; 

    NSString *myString = @"Hello"; 

    [pool release]; 
} 

Ist das richtig?

-(void) doSomething { 

    NSAutorelease *pool = [[NSAutorelasepool alloc] init]; 

    NSString *myString = [[NSString alloc] initWithString:@"Hello"]; 

    [pool release]; 
} 

oder das?

-(void) doSomething { 

    NSAutorelease *pool = [[NSAutorelasepool alloc] init]; 

    NSString *myString = [[NSString alloc] initWithString:@"Hello"]; 

    [myString release]; 
    [pool release]; 
} 

Meine Frage ist im Besitz Objekte im Rahmen des Autofreigabepools erstellt müssen speziell relased werden oder ist die betreut, wenn der autorelasepool freigegeben wird worden?

Teo

Antwort

1

Autorelease-Pool behandelt die automatisch freigegebenen Objekte. Wenn Sie ein Objekt besitzen (via Alloc oder Copy oder Retain), müssen Sie es freigeben. Dein zweites Beispiel ist also nicht korrekt. Wenn Sie die Zeichenfolge zugewiesen haben, besitzen Sie sie und Sie müssen sie freigeben.

Ein Autorelease-Pool wird für den Hauptthread erstellt. (Sie können in die Hauptfunktion schauen, wenn Sie wollen). Jeder Thread benötigt einen eigenen Autorelease-Pool, um automatisch freigegebene Objekte zu verwalten. Wenn Sie einen anderen Thread erstellen, müssen Sie daher einen Autorelease-Pool für diesen Thread erstellen. Selbst wenn Sie nicht automatisch freigegebene Objekte im Thread erstellen, sollten Sie dies als Bibliotheksaufrufe in diesem Thread erstellen, um automatisch freigegebene Objekte zu erstellen.Selbst wenn Sie sicher sind, dass keine Bibliotheksaufrufe automatisch freigegebene Objekte erstellen, sollten Sie sie auch als bewährte Methode erstellen, insbesondere wenn Sie an einem großen Projekt arbeiten, das von mehreren Personen entwickelt und verwaltet wird.

0

Sie brauchen nur Ihre eigenen Autofreigabepool erstellen, wenn Sie eine Reihe von Autoreleased Objekte erstellen Sie Müll wollen sammeln sofort. Sie haben jedoch Recht damit, dass Sie keine "automatisch freigegebenen" Objekte referenzieren möchten, die Sie erstellen, nachdem Sie den Pool freigegeben haben. Automatisch freigegebene Objekte (die Sie nicht behalten) werden zerstört, wenn der Pool leer ist.

Da keines der Objekte in Ihrem Beispiel eine Autorelease aufweist, ist das Erstellen eines eigenen Autorelease-Pools im Wesentlichen ein No-Op.

+0

Eigentlich spricht er über Thread. Also Autorelease Pool ist notwendig. – taskinoor

+0

Was, wenn er keine automatisch freigegebenen Objekte erstellt? – zoul

+0

@zoul, bitte überprüfen Sie den letzten Teil meiner Antwort. Auch wenn Sie dem vielleicht nicht zustimmen, werde ich lieber den Best Practices folgen. – taskinoor

0

Keines Ihrer Beispiele benötigt einen Autorelease-Pool. Autorelease-Pools nur kümmern Autoreleased Objekte:

NSArray *foo = [NSArray array]; 
NSObject *bar = [[[NSObject alloc] init] autorelease]; 

Ihre erste Zeichenfolge initialisiert wird unter Verwendung eines Stringliteral und ist daher wohl besondere in Bezug auf die Speicherverwaltung (vielleicht jemand anderes weiß mehr). Ihr zweiter String leckt, der Pool macht keinen Unterschied. Ihr dritter String wird korrekt freigegeben, der Pool macht keinen Unterschied mehr.

Hier können Sie einen Pool brauchen würden:

- (void) someMethodThatRunsOnAThread { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    NSString *foo = [@"foo" uppercaseString]; 
    [pool drain]; 
} 

die foo Saite würde Leck hier, wenn der Pool nicht da ist. Beachten Sie, dass ich drain anstelle von release auf dem Pool anrufe - auf iOS gibt es keinen Unterschied, aber in Müll-gesammelte Umgebungen unterscheiden sich die beiden, so ist es wahrscheinlich besser, sich angewöhnen, den richtigen Anruf.

Beachten Sie auch, dass Sie möglicherweise einen Pool benötigen, obwohl Sie selbst keine Objekte automatisch freigeben, da im Code, den Sie in Ihrer Methode aufrufen, viele Speichervorgänge ausgeführt werden können.

+0

Eigentlich redet er über Thread. Ich denke, die Beispielmethoden laufen auf einem separaten Thread. – taskinoor

+0

Sie benötigen keinen Autorelease-Pool für einen Thread, wenn Sie keine automatisch freigegebenen Objekte erstellen. – zoul

+0

Bitte überprüfen Sie den letzten Teil meiner Antwort. Auch wenn Sie dem vielleicht nicht zustimmen, werde ich lieber den Best Practices folgen. – taskinoor

0

Denken Sie, dass dies etwas so sein sollte:

-(void) doSomething { 

    NSAutorelease *pool = [[NSAutorelasepool alloc] init]; 


    NSString *myString = [[[NSString alloc] initWithString:@"Hello"] autorelease]; 

    // or create string like this (automatically autoreleased) 
    NSString *myString = [NSString stringWithString:@"Hello"]; 

    [pool release]; 
} 

Sie müssen Autorelease-Nachricht senden, um Objekte innerhalb Autofreigabepool. Sie werden freigegeben, wenn die Freigabemeldung an den Pool gesendet wird.

+0

Überlassen Sie nicht den Pool, indem Sie sowohl "-drain" als auch "-freigabe" senden? – zoul

+0

oops ... ja ... :) – marko