2012-02-21 77 views
3

保留對象的設置器是否自動首先釋放對象?保留屬性保留/釋放合成設置器

我還沒有ARC工作,因此我有這些問題。

假設我有一個的ivar這種方式定義的:

ObjectClass *anObject_; 

隨着歡迎使用屬性

@property (nonatomic, retain) ObjectClass *anObject; 

而且合成使用

@synthesize anObject = anObject_; 

如果我有正在使用自動合成的設定器保留屬性,如果需要,setter將首先執行發佈像這樣:

- (void) setAnObject:(ObjectClass*)anObject { 
    if (anObject_) [anObject_ release]; 
    anObject_ = [anObject retain]; 
} 

並能在簡單地進行分配的對象,而無需首先釋放它

我可以通過將屬性分配給無來釋放對象嗎?(如果有其他業主,這可能是不安全的。)

self.anObject = nil; 

換句話說,我可以用if (anObject_) [anObject_ release];代碼分配的setter之外,讓合成的二傳手我做到這一點?

如果我編寫自己的setter,是否需要添加/包含保留如果一個合成的setter包含發佈(這是我最初的問題),我需要添加/包含這個,在我自己的setter

最後一件事 - 當使用ARC時,我假設self.anObject = nil;self.anObject = anthingelse;都是安全的無論我的代碼是,原始對象都將被髮布?

回答

3

答案几乎每一個你的問題是肯定的。保留和發佈將被添加到您的代碼,以使其正確。具體而言,strong屬性的setter將釋放其當前值並保留其新值。即使您不使用合成訪問器並編寫自己的代碼,它們仍然會有正確的行爲。事實上,在ARC下,您甚至不允許在您自己的代碼中調用retainrelease

你似乎有點糊塗上的一個點如下:

我可以通過分配屬性爲nil釋放對象? (如果有其他業主這 可能是不安全的。)

這是真的,當你的屬性設置爲無,release將在對象上調用。但請記住,這並不一定意味着該對象將被解除分配:只有在保留計數變爲0時纔會發生。

當我們說一個對象擁有另一個對象,通常是指該物體具有很強的參考其他對象,這樣retain是在分配調用。只要對象此時至少有一個其他所有者,則將該屬性設置爲nil不會導致它被釋放。

如果您使用的是ARC,您可以更簡單地考慮所有這些問題。忘記retainrelease,只需考慮對象所有權。只要某個其他對象擁有該對象(具有strong引用),對象就不會被釋放。而要記住的唯一缺陷是循環:如果兩個對象彼此擁有,那麼它們就不能被釋放。

+0

如果我理解正確的話,我可以將保留的屬性值設置爲零(或任何其他值),並且這將始終釋放第一個即使當我編寫了明確的setter包括'if(anObject_ )[anObject_ release];'代碼。你能證實這一點嗎? – Draco 2012-02-21 23:01:39

+0

如果你寫了一個setter,然後將它的屬性設置爲'nil',那麼即使你沒有在你編寫的setter中調用'release',也會在舊對象值上調用release。事實上,當你使用ARC時,你不允許**在你的setter(或其他地方)調用'release'。 – yuji 2012-02-21 23:03:38