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