2015-05-29 91 views
0

其大家都很熟悉的常見問題,但我還是不完全理解。父母子女建設保留週期

如果對象A擁有(具有強屬性)對象B,而對象B具有對象A的強屬性,則存在保留週期,並且不會釋放對象並存在內存泄漏。

但是,如果對象A改爲指向對象C而不是對象B,那麼內存中的另一個地址呢?

據我所知,強大的性能做類似如下:

- (void)setObject:(id)newObject{ 
if (_newObject == newObject){ 
return; // 
} 

NSObject *oldObject = _newObject; 
_newObject = [newObject retain]; 
[oldObject release]; 
} 

那麼,如果我們點而不是爲對象C,是不是在這種情況下內存對象B將被釋放?如果兩個對象(A和B)將相反設置nil對象,該怎麼辦?內存泄漏是否還會有保留週期?在舊的價值「浮動」在內存的某個地方?

我知道,這已經討論過很多次了,但我仍然無法在我的腦海中看到「全貌」。我很感謝在這方面的任何澄清。

+0

分配工具有助於輔助週期檢測的工具。我建議你探索一下這些工具。如果你想編寫示例代碼來玩,創建你自己的NSObject子類,這樣你就不會遇到靜態實例(比如@「foo」)或標籤指針。 – bbum

回答

2

您正在尋找的詞是「保留週期」。

最簡單的保留週期將是一個對自身有強烈參考的對象。非常罕見,因爲它毫無意義。

最常見的情況是A對B和B有強烈的參考,對A有很強的參考A→B→A。你看到這個循環?

該循環可以是任何長度A-> B-> C-> D-> E-> F-> G-> - > A。這是一個保留週期,所以什麼都不會發布。如果您只有A-> B-> C-> D - > ...-> Z且沒有引用返回序列中的另一個對象,則不存在循環。沒有周期,沒有問題。

+0

所以,如果我們有循環A> B> A,然後我們做A> C和B> D,具有相同的強參考,那麼就不會有內存泄漏,因此保留循環? –

+1

順便說一句,那些對自身有強烈引用的對象並不少見,因爲Swift中的對象可以有閉包作爲它們的屬性,一旦你訪問了「self」的任何屬性或方法,它就會強烈地引用「self」在那封閉之內。 Obj-C塊也可以通過'self'導致保留週期,如下所示:http://stackoverflow.com/questions/4352561/retain-cycle-on-self-with-blocks?rq=1 –

+0

@EvgeniyKleban這兩個答案和JeremyP的答案是正確的。 – bbum

3

如果問題是「你可以通過重新分配一個屬性來打破保留週期嗎?」,答案是肯定的。如果您將nil指定給屬性,則同樣適用。

+0

如果只是其中一個屬性會被重新分配 - 設爲零,這足以擺脫保留循環? –

+1

是的。因爲當兩者都相互引用時,循環存在。所以如果A - > B但是B - > NIL,你沒有循環。但這都是學術性的,你應該使用強大的A-> B和弱的B-> A(或分配,但通常是弱的是合適的)。 –