一.iOS在切換根控制器時,如何銷毀之前的控制器?(切換rootViewController時注意的內存泄漏)
首先、在iOS的ARC機制下,任何對象,當沒有其他對象對他進行強引用時,都會被自動釋放。
而控制器的切換主要為兩種方式 push和present modally。
1.0 push出來的子控制器,導航欄控制器會對該子控制器進行強引用(本質就是入棧,在入棧的過程中,可能不止是導航欄控制器對子控制器有強引用)
其中 push 對應着 pop 則控制器會被銷毀。其push的本質是入棧,所有的子控制器放在數組中,先進后出,如果導航欄作為根控制器。此時需要更該根控制器,不管push了多少子控制器入棧了。其最后只需要在當前顯示的子控制器中對根控制器重新賦值即可。即原先的導航欄控制器沒有對象強引用它,它會被釋放,其所有的子控制器自然都會被釋放了(前提是你本身代碼不存在其他內存泄漏)
UIApplication.shared.keyWindow?.rootViewController = newRootVC
1.1 誰來調用這消失presented VC的這個方法:正確的做法是“誰污染誰治理”,對於彈出模態,系統指定了銷毀的方法dismiss,其中動畫效果暫時關閉(原因在后面)
dismiss(animated: false, completion: nil)
舉例: 在我們的項目中假如需要在firstVC2控制器進行根控制器的切換。firstVC2控制器是這樣來的:
ViewController push ---->firstVC1 present--->firstVC2 。則如何在firstVC2中切換根控制器,並同時銷毀之前的控制器。則必須先dismiss掉 firstVC2 。實現如下:
dismiss(animated: false) {
UIApplication.shared.keyWindow?.rootViewController = newRootVC
}
分析:如果不dismiss掉 firstVC2,則firstVC2不會被釋放。firstVC2無法釋放,必然導致firstVC1無法釋放,而棧頂元素無法被釋放,棧頂下面的控制器都無法釋放。
注意:
1.動畫狀態必須關閉,根控制器的切換與dismisse的動畫同時進行會給用戶帶來較差的體驗效果。
2在項目開發中,只要有present出來的控制器,一定要有對應的dismiss,否則項目中會存在無法估量的bug