16

Ich las in der Dokumentation von Apple über Management-Speicher, wenn ich zu Autofreigabepool Blöcke bekam und etwas hat mir denken.iOS Autofreigabepool Blöcke

Any object sent an autorelease message inside the autorelease pool block is 
released at the end of the block. 

Ich bin mir nicht sicher, ob ich das vollständig verstehe. Jedes Objekt, das in einem Autorelease-Pool-Block erstellt wird, wird trotzdem am Ende des Blocks freigegeben, da dies die Lebensdauer ist. Warum müssen Sie die Autorelease für das Objekt aufrufen, wenn es am Ende der Blockierung trotzdem freigegeben wird?

Um klarer, werde ich ein Beispiel geben, was ich denke ich:

@autoreleasepool { 

    MyObject *obj = [[MyObject alloc] init]; // no autorelease call here 

    /* use the object*/ 
    //.... 
    // in the end it should get deallocated because it's lifespan ends, right? 
    // so why do we need to call autorelease then?! 
    } 

PS: Bitte mich nicht, weil der ARC sagen, dass wir einige Dinge nicht tun müssen, um weil ARC sich um sie kümmert. Ich bin mir dessen voll bewusst, aber ich möchte ARC für einige Momente beiseite lassen, um den Mechanismus der Speicherverwaltung zu verstehen.

Antwort

27

Autorelease entfernt nur einen Beibehaltungszähler aus dem Objekt, um es nicht „frei“ der Speicher sofort wie in c. Wenn der Autorelease-Pool endet, wird für alle automatisch freigegebenen Objekte mit einer Anzahl von 0 Speicherplatz freigegeben.

Manchmal erstellen Sie viele Objekte. Ein Beispiel wäre eine Schleife, die bei jeder Iteration neue Zeichenfolgen erstellt und der Zeichenfolge neue Daten hinzufügt. Sie benötigen möglicherweise die vorherigen Versionen der Zeichenfolge nicht und möchten Speicherplatz freigeben, der von diesen verwandt wird. Sie können dies erreichen, indem Sie explizit den Autorelease-Pool verwenden, anstatt darauf zu warten, dass er auf natürliche Weise ausgeführt wird.

//Note: answers are psudocode 

//Non Arc Env 
@autoreleasepool 
{ 

    MyObject *obj = [[MyObject alloc] init]; // no autorelease call here 
    //Since MyObject is never released its a leak even when the pool exits 

} 
//Non Arc Env 
@autoreleasepool 
{ 

    MyObject *obj = [[[MyObject alloc] init] autorelease]; 
    //Memory is freed once the block ends 

} 
// Arc Env 
@autoreleasepool 
{ 

    MyObject *obj = [[MyObject alloc] init]; 
    //No need to do anything once the obj variable is out of scope there are no strong pointers so the memory will free 

} 

// Arc Env 
MyObject *obj //strong pointer from elsewhere in scope 
@autoreleasepool 
{ 

    obj = [[MyObject alloc] init]; 
    //Not freed still has a strong pointer 

} 
+0

also wie beantwortet das meine frage? Ich habe nur ein einfaches Beispiel gegeben, um Antworten wie diese zu vermeiden, die nicht viel mit der Frage zu tun haben.Ich habe dem kleinen Beispiel auch Kommentare hinzugefügt. – Teo

+1

Normalerweise verwenden Sie nur Autorelease-Pools in einer Funktion mit hoher Speicherauslastung, die Sie früher als normal freigeben müssen. Der Absatz sollte einen Kontext hinzufügen. – Kibitz503

+0

Ok, also auf einem nicht ARC-env, '' MyObject * obj = [[MyObject alloc] init]; '' in einem Autorelease-Pool wäre ein Speicherleck, aber auf einem ARC-env fügt der Compiler automatisch einen Freigabeaufruf für die Objekt oder warum es kein Speicherleck mehr ist? – Teo

6

(. Meistens sind nur einige zusätzliche Hintergrundinformationen zu geben; @ Kibitz503 wird Sie an die richtige Antwort zu bekommen)

@autoreleasepool { 

    MyObject *obj = [[MyObject alloc] init]; // no autorelease call here 

    /* use the object*/ 
    //.... 
    // in the end it should get deallocated because it's lifespan ends, right? 
    // so why do we need to call autorelease then?! 
} 

PS: Bitte erzählen Sie mir nicht, dass wir wegen der ARC don‘ Ich muss einige Dinge tun, weil ARC sich um sie kümmert. Ich bin mir dessen voll bewusst, aber ich möchte ARC für einige Momente beiseite lassen, um den Mechanismus der Speicherverwaltung zu verstehen.

OK, lassen Sie uns nicht berücksichtigen ARC. Im obigen Beispiel würde obj ohne ARC nicht freigegeben werden. Nur weil ARC zusätzliche release Anrufe fügt tut möglicherweise deallokierten erhalten (Ihr Beispiel gegeben, haben wir eigentlich keine Ahnung, da wir nicht wissen, was in use the object passiert).

Wie @ Kibitz503 erklärt: "Release" bedeutet nicht "ausplanen." Am Ende des Blocks wird der Autorelease-Pool gelöscht, dh alle anstehenden autorelease Aufrufe werden am Ende des Blocks als release gesendet. Wenn das dazu führt, dass das Objekt eine Zählung von 0 erreicht, wird es freigegeben.

Aber ob die oben in einem Block oder nicht, ohne ARC es ein Leck vorhanden ist.

+0

Gute Aufklärung über das Leck. Es ist ein Leck mit oder ohne den Autorelease Pool umwickelt! – Kibitz503

+0

Bedeutet das, dass, wenn ich ARC verwende und ein Objekt irgendwo außerhalb des "@autoreleasepools" {}} freigibt, das Objekt bis zum Ende des @autoreleasepool-Blocks noch existiert? – confile

+0

Es hängt vom Code ab. Am Ende des Autorespulepool-Blocks werden alle anstehenden Autoreleases gesendet, die in diesem Block erstellt wurden. Ich weiß nicht, was "ein Objekt freigeben" in Ihrem Beispiel bedeutet. Sie möchten wahrscheinlich ein bestimmtes Codebeispiel zusammenstellen und eine neue Frage stellen. –

0

Autorelease Pools verschieben Freigabe des Objekts bis zum Ende des Pools, die die Möglichkeit vermeidet freigegeben werden, bevor sie das Ende erreicht. Es ist also im Grunde sicherzustellen, dass das Objekt nicht vor dem Ende des Pools freigegeben wird.