Das Aufrufen [objectInstance autorelease]
fügt dem aktuellen NSAutoreleasePool
ein Objekt hinzu. Wenn dieser Pool eine Nachricht drain
empfängt, sendet es eine release
an alle Objekte in dem Pool. Wenn eines der RetainCount-Objekte dieser Objekte 0 erreicht, werden sie an diesem Punkt freigegeben. Der Zweck der Autorelease ist es, Ihnen zu erlauben, ein Objekt zu markieren, das "irgendwann in der Zukunft" veröffentlicht werden soll. Dies ist besonders nützlich für Dinge wie Methoden, die ein neu zugewiesenes Objekt zurückgeben, es aber freigeben wollen, so dass der Aufrufer nicht das Eigentum des zurückgegebenen Objekts übernehmen muss. Ein Verfahren könnte wie folgt aussehen:
- (id)myMethod {
id myObj = [[SomeClass alloc] init];
...
return [myObj autorelease];
}
Der Anrufer von myMethod
würde dann retain
der Rückgabewert, wenn sie das Eigentum an dem zurückgegebene Wert nehmen wollten oder es ignorieren, wenn nicht. Wenn der aktuelle NSAutoreleasePool
leer ist, wird myObj
eine Freigabenachricht erhalten. Wenn es keine anderen Objekte besitzt (d. H. Es hat eine retain
Nachricht gesendet), wird es freigegeben.
All dies wird im Cocoa Memory Management Programming Guide erklärt. Selbst wenn Sie es bereits gelesen haben, ist es immer eine andere Lektüre wert.
Also, Ihre Fragen zu beantworten:
Zunächst sollten Sie theBackendResponse
freigeben. Sie werden Speicher verlieren, wenn Sie dies nicht tun. Sie müssen nicht wissen, was accountDictionary
mit dem String tut: Wenn es einen Verweis behalten muss, hat es theBackendResponse
behalten. Sie haben ein Eigentumsrecht an theBackendResponse
, weil Sie alloc
'd es, so müssen Sie dieses Eigentum (über release
oder indirekt über autorelease
) aufgeben.
Zweitens müssen Sie das Argument beibehalten oder in setAccountDictionary:
kopieren, wenn Sie einen Verweis auf das Objekt bzw. den Wert beibehalten möchten.Die Standard-Setter-Methode sieht ungefähr so aus (vorausgesetzt, Sie brauchen keine Atom Semantik):
- (void)dealloc {
[accountDictionary release];
[super dealloc];
}
Da Sie mit zu sein scheinen:
-(void)setAccountDictionary:(NSDictionary*)newDict {
if(newDict != accountDictionary) {
id tmp = accountDictionary;
accountDictionary = [newDict copy]; //Since newDict may be mutable, we make a copy so that accountDictionary isn't mutated behind our back.
[tmp release];
}
}
Sie auch release
accountDictionary im dealloc Verfahren erinnern müssen NSViewController
, ich nehme an, Sie sind auf Leopard (OS X 10.5) in diesem Fall sollten Sie wahrscheinlich verwenden und die @synthesize
d Getter/Setter wenn möglich. Um dies zu tun, fügen Sie eine
@property (copy,readwrite) NSDictionary * accountDictionary;
Erklärung zur Klasse @interface
. Und fügen Sie eine @synthesize accountDictionary;
Direktive in den @implementation
Block für Ihre Controller-Klasse hinzu.
Beeindruckende Antwort. –
Fantastisch, danke. Jetzt verstehe ich. Ich bin eigentlich auf dem iPhone, mit UIViewControllers, aber offensichtlich gilt Objective-C 2.0 noch. Ich werde keine synthetischen Getters/Setter für diesen verwenden, aber ich werde in der Zukunft. Danke noch einmal! – AriX
Dies ist ein wenig falsch, Sie sollten das alte Objekt niemals freigeben, bevor Sie das neue Objekt behalten/kopieren. Wenn 'accountDictionary' sich auf' newDict' bezieht, wird der Aufruf von 'release' zuerst ausgelöst.Ich gebe eine alternative Lösung als Antwort an, da ich keinen mehrzeiligen Code hinzufügen kann –