2012-06-20 73 views
9

所以我有一個支持iOS 4的項目,所以我所有的IBOutlets都是__unsafe_unretained甚至是IBOutlets,它們都位於控制器主視圖(獨立視圖在同一個nib中)之外,並且都工作得很好。弱和unsafe_unretained之間的區別

所以,時間已經到了,現在的客戶希望支持的iOS 5所以我們的團隊改變了所有的__unsafe_unretained IBOutlets爲__weak IBOutlets但現在不被設置爲nil(除viewdidload)主視圖內IBOutlets所以我們無法在稍後添加它們。

如果我考慮一下,它是有道理的,因爲如果沒有視圖(主視圖)保留這些IBOutlet,它們應該被釋放並歸零(我不知道這是否是正確的詞),所以解決方案是除去那些IBOutlets

__weak什麼沒有意義對我來說是爲什麼unsafe_unretainedweak之間的不同的行爲,在我腦海中的那些unsafe_unretained應該被釋放,當應用程序試圖訪問他們,他們應該指向到一個無效的引用,然後應用程序應該崩潰。

我認爲unsafe__unretained是一樣弱,但沒有歸零。

我在這裏錯過了什麼嗎?

謝謝。

+4

你是對的。 unsafe_unretained不包含引用。 – Francesco

回答

5

我認爲unsafe__unretained是一樣弱,但沒有歸零。

是的,是的。

當Cocoa加載筆尖時,它會創建所有自動釋放的對象,因此當調用viewDidLoad時它們仍然存在。但是,autorelease池的壽命在控制權返回到運行循環時結束。此時,所有不屬於任何物品的物品都將消失,因此任何弱點將在此時歸零。

對於大多數網點來說,這不是問題,因爲NIB中的對象通常已由某些東西擁有。因此,例如,視圖中的按鈕由其父視圖所有。因此,指向該按鈕的強大銷售點因此過度或更糟可能會導致保留週期。

頂層對象顯然沒有父視圖來擁有它們,所以它們需要由其他東西所擁有,例如一個控制器或「文件所有者」。如果你發現東西消失,你需要在File的所有者中爲它創建一個強大的IBOutlet。

詳情請見Apple's docs

+1

這使得很多的意義,我完全意識到這一點,但我的問題是,爲什麼當我使用unsafe_unretained那些IBOutlets永遠不會被釋放,我可以使用它們,每當(時間)我想要的? – Ecarrion

+0

@Ecarrion,在我看來,它一直存在,直到內存塊沒有被覆蓋/覆蓋。而當它被覆蓋的應用程序獲取訪問不良。 – MANN

0

你是對的,當試圖通過陳舊的__unsafe_unretained引用訪問釋放對象時,應用程序會崩潰。

它不會的原因很​​可能是因爲您的應用程序的某些其他部分引用了強引用。

嘗試在啓用殭屍的情況下運行,這會在解引用假定的陳舊指針時導致立即崩潰。

1

對於將來遇到這個問題的用戶,我認爲CRD的Stackoverflow answer也可以解釋爲類似的問題。即使對象已被釋放,由不安全的未保留指針(包含實際對象數據)引用的內存也不一定爲零,因此事情似乎可以正常運行,直到內存被實際重用/修改/歸零爲止。