2010-02-17 7 views
7

Ich bin neu zu objektiven c und versuche zu verstehen, wie/wann Autorelease aufgerufen wird. Ich verstehe den einfachen Anwendungsfall:Ist die automatische Freigabe eines Fehlers in Ziel c?

- (void) foo { 
    Bar *b = [[[Bar alloc] init] autorelease]; 
    [self doSomething:b]; 
    } 

Was ist mit diesem nächsten Fall - das ist ein Fehler, weil das Objekt unmittelbar nach dem Verlassen des Umfangs der makeBar veröffentlicht?

-(Bar*) makeBar 
{ 
    return [[[Bar alloc] init] autorelease]; 
} 

Was ist, wenn der Anrufer eine Rücklage hält?

Bar *b = [[self makeBar] retain]; 

Danke, -Eric

+1

Der Inhalt dieser Frage und die zwei Antworten unten sollten in der Liste der erforderlichen Literatur für die neuen ObjC – ckhan

Antwort

7

In Ihrem zweiten Beispiel, das anonyme Objekt sind Rückkehr werden Sie nicht so schnell freigegeben werden, wenn die Ausführung der Umfang der makeBar verlässt, sondern auf die nächste Iteration des Laufes Schleife. Dies gibt Ihnen die Möglichkeit, retain es in jeder Methode makeBar

Also Ihr letztes Beispiel ok genannt, da die Zählung unter fallen nicht behalten 0

Sind Sie damit Probleme haben?

+1

sein. Genauer gesagt wird es veröffentlicht, wenn der Autorelease-Pool, dem es hinzugefügt wurde, abgelassen/freigegeben wird. Dies ist normalerweise am Ende einer Laufschleife, aber nicht immer. – dreamlax

+0

Keine Probleme, ich habe gerade meinen Code auf mögliche Speicherprobleme untersucht und das Muster aus dem Beispielcode, den ich kopiert hatte, gesehen und war mir nicht sicher, ob es ein Fehler war oder nicht. – esilver

5
-(Bar*) makeBar 
{ 
    return [[[Bar alloc] init] autorelease]; 
} 

Der zweite Fall ist die bevorzugt Art und Weise ein Objective-C Objekt zurückzukehren. Außer +alloc, -copy... und -create... sollte das Verfahren kein Eigentum des zurückkehrenden Objekt beibehalten, dh die (Änderung) behalten Zahl 0.

jedoch sein sollte, macht [[Bar alloc] init] das Objekt retainCount von 1 zu haben, sollte man zu Freigabe vor der Rückkehr. Aber -release wird sofort das Objekt freigeben, wodurch die Methode unbrauchbar wird. Deshalb -autorelease verwendet - es ist ein verzögert ist -release, dh das Objekt wird schließlich freigegeben werden, aber nicht jetzt, so dass andere Teile des Codes können mit ihm noch in Wechselwirkung treten, doch die Beibehaltungszähler noch auf 0 ausgeglichen werden können


Bar *b = [[self makeBar] retain]; 

Sie sollten nicht behalten es es sei denn Sie b ein langfristiger Besitzer des Objekts sein wollen.