2012-09-27 50 views
6

我作爲一個工作在iOS遺留代碼上的大團隊的一員工作,目標iOS環境爲4.3及更高版本。我看到其他開發人員檢查從NSObject下降的類,但沒有dealloc方法。我也看到UIViewController後代不包括viewDidUnload方法。當我詢問這個​​代碼時,通常的回答是「別擔心,ARC現在就照顧好這個。」在使用ARC之前,iOS6之前還需要'dealloc'和'viewDidUnload'方法嗎?

我明白viewDidUnload通過調用viewDidLoad調用時的iOS經驗內存不足的條件下,通過釋放可重新創建的對象釋放內存的一個目標,當一個對象的保留計數降爲零dealloc被調用。對於UIViewController對象和後代,這可能意味着'viewDidUnload'可能會或可能不會在dealloc之前被調用。

所以這裏是我的問題:在iOS 6之前的iOS版本上使用ARC時,仍然需要deallocviewDidUnload方法嗎?

如果答案是「是!」,那麼我將需要很好的理由和/或文件來進行論證。

期待您的回覆。 (感謝Tommy幫助我收緊我的問題。)

回答

14

viewDidUnloadis deprecated。所以不管是ARC,你不僅需要一個,而且不應該使用一個。陳述的理由是觀點不再被低清記憶警告清除(可能是因爲他們現在貢獻得太少而不值得響應命中);如果部分理由是,許多人認爲他們可以釋放在viewDidUnload之內的viewDidLoad中創建的所有資源,並且僅憑這一點就可以防止泄漏,我不會感到驚訝。這是不正確的,因爲viewDidUnload是 只有在卸載視圖時纔會調用,因爲內存不足警告。它在正常生命週期中不被調用。

ARC's new rules

,如果你需要管理比釋放實例變量 其他資源,您可以實現一個dealloc方法。你不必(實際上 你不能)釋放實例變量

編輯:4.3及更高版本上專門發表評論......

ARC將不執行一個版本的viewDidUnload你。viewDidLoad/viewDidUnload週期的一點是,如果因爲任何原因視圖層次結構的任何部分出現故障,那麼在低內存警告時不會自動釋放,但這樣做不會給您帶來任何好處,因爲只要視圖下一次加載,您保留的任何內容都將被替換爲新的副本。因此,如果您有strongIBOutlet s的觀點,無論如何都應該在self.view之下的層次結構內,那麼最好在viewDidUnload期間將它們清零。即使你有weak參考,這是一個很好的地方,以防止自己發揚任何懸掛指針。

從iOS 5開始,你可以擁有自我調零的弱引用,所以如果你支持5+,那麼使用這些引用並且不執行viewDidUnload將是一種好方法。如果您使用強引用並忽略viewDidUnload,則4.3可能最終會阻止您完全響應Apple提供的低內存警告,但您不會泄漏內存。如果你使用弱引用,那麼在有時候你可能沒有視圖的時候,你需要小心不要引用任何這些對象(也就是說,任何時候你沒有顯示,但視圖之前已經加載 - setters在調整視圖但受另一個視圖影響的控制器上也是一個典型示例;例如,如果您正在通過鍵值觀察來更新字段)。

您可以使用模擬器的「模擬內存警告」在一定程度上測試和調試這些內容。

無論iOS版本如何,ARC提供的dealloc都是相同的。但是它只會覆蓋Objective-C對象。當他們說你不能釋放實例變量時,它們意味着它發送release消息給他們。假設你有Core Foundation對象或者執行了純C內存分配,那麼你需要實現一個處理所有這些的dealloc

很明顯,Instruments和Leaks工具是測試和調試該區域的方法;任何時候內存泄漏都要小心,以檢查創建該內存的對象的類型是否也在泄漏。直接對象可以很好,但是它的分配會出現在泄漏列表中,如果它不是dealloc,因爲有人泄漏了它。

+0

對不起,@Tommy,我對目標iOS版本的問題還不夠清楚。將根據您的答案更新問題。 :) – tychoD

+0

謝謝,這確實回答了我的問題。 :D – tychoD

+0

我必須在dealloc()中清除所有的@properties嗎? –

6

viewDidUnload現已被棄用,不再由系統調用(截至iOS 6)。它從來沒有像蘋果希望的那麼有用,而且比它值得的更麻煩。這與ARC無關。

dealloc通常在ARC下不需要,但在需要非ARC資源管理的情況下仍然是必需的。例如,如果您需要使用free()或以其他方式發佈資源。這也是一個以觀察員或代表身份去除自己的好地方。但是很多課程現在不需要dealloc

相關問題