每個(gè)ios開發(fā)者對loadView和viewDidLoad肯定都很熟悉,雖然這兩個(gè)函數(shù)使用上真的是非常簡單,但是和類似的initWithNibName/awakeFromNib/initWithCoder放在一起還是非常容易讓人混淆的.
一、loadView
永 遠(yuǎn)不要主動(dòng)調(diào)用這個(gè)函數(shù)。view controller會(huì)在view的property被請求并且當(dāng)前view值為nil時(shí)調(diào)用這個(gè)函數(shù)。如果你手動(dòng)創(chuàng)建view笑撞,你應(yīng)該重載這個(gè)函數(shù)。如 果你用IB創(chuàng)建view并初始化view controller皮获,那就意味著你使用initWithNibName:bundle:方法麻诀,這時(shí)献酗,你不應(yīng)該重載loadView函數(shù)初家。
這個(gè)方法的默認(rèn)實(shí)現(xiàn)是這樣:先尋找有關(guān)可用的nib文件的信息偎窘,根據(jù)這個(gè)信息來加載nib文件,如果沒有有關(guān)nib文件的信息笤成,默認(rèn)實(shí)現(xiàn)會(huì)創(chuàng)建一個(gè)空白的UIView對象评架,然后讓這個(gè)對象成為controller的主view。
所以炕泳,重載這個(gè)函數(shù)時(shí),你也應(yīng)該這么做上祈。并把子類的view賦給view屬性(property)(你create的view必須是唯一的實(shí)例培遵,并且不被其他任何controller共享)浙芙,而且你重載的這個(gè)函數(shù)不應(yīng)該調(diào)用super。
如果你要進(jìn)行進(jìn)一步初始化你的views籽腕,你應(yīng)該在viewDidLoad函數(shù)中去做嗡呼。在iOS 3.0以及更高版本中,你應(yīng)該重載viewDidUnload函數(shù)來釋放任何對view的引用或者它里面的內(nèi)容(子view等等)皇耗。
這個(gè)網(wǎng)上的資料都說的很不全面南窗,尤其是藍(lán)色字部分。
二郎楼、viewDidLoad
這個(gè)函數(shù)在controller加載了相關(guān)的views后被調(diào)用万伤,而不論這些views存儲(chǔ)在nib文件里還是在loadView函數(shù)中生成。而多數(shù)情況下是做nib文件的后續(xù)工作呜袁。
網(wǎng)上資料對這個(gè)函數(shù)的描述則完全不對敌买。
三、viewDidUnload
這 個(gè)函數(shù)是viewDidLoad的對立函數(shù)阶界。在程序內(nèi)存欠缺時(shí)虹钮,這個(gè)函數(shù)被controller調(diào)用,來釋放它的view以及view相關(guān)的對象膘融。由于 controller通常保存這view以及相關(guān)object的引用芙粱,所以你必須使用這個(gè)函數(shù)來放棄這些對象的所有權(quán)以便內(nèi)存回收。但不要釋放那些難以重 建的數(shù)據(jù)氧映。
通常controller會(huì)保存nib文件建立的views的引用宅倒,但是也可能會(huì)保存著loadView函數(shù)創(chuàng)建的對象的引用。最完美的方法是使用合成器方法:
1
self.myCertainView = nil;
這樣合成器會(huì)release這個(gè)view屯耸,如果你沒有使用property拐迁,那么你得自己顯示釋放這個(gè)view。
網(wǎng)上對這個(gè)函數(shù)的描述含含糊糊疗绣,看了等于沒看线召。
四、結(jié)論
所以流程應(yīng)該是這樣:
(loadView/nib文件)來加載view到內(nèi)存 ——>viewDidLoad函數(shù)進(jìn)一步初始化這些view ——>內(nèi)存不足時(shí)多矮,調(diào)用viewDidUnload函數(shù)釋放views
—->當(dāng)需要使用view時(shí)有回到第一步
如此循環(huán)
需要厘清兩個(gè)概念,創(chuàng)建一個(gè)類和實(shí)例化一個(gè)類.在XCode中創(chuàng)建一個(gè)類和實(shí)例化一個(gè)類很容易區(qū)分,但是在IB(Interface Builder)中有時(shí)候就會(huì)迷糊.其實(shí)也很好區(qū)分,孤零零地創(chuàng)建了一個(gè)nib文件,沒有和其他可被實(shí)例化的類有直接或間接關(guān)系的時(shí)候,這個(gè)類或這些類 (一個(gè)nib文件俺也可能包含多個(gè)類)是沒有機(jī)會(huì)被實(shí)例化的,所以這種情況只是通過ib創(chuàng)建了一個(gè)類,而沒有實(shí)例化.真正的實(shí)例化還需要通過在Xcode 用代碼來讀取這個(gè)nib文件.知道這兩這的區(qū)別后這些方法也就容易辨認(rèn)多了
viewDidLoad其實(shí)沒什么可混淆的,無論通過什么途徑加載(Xcode或者IB,這里的加載屬于實(shí)例化)完view后肯定會(huì)執(zhí)行這個(gè)方法.
loadView需要分兩種情況.當(dāng)你通過Xcode實(shí)例化一個(gè)類的時(shí)候就需要自己在controller中實(shí)現(xiàn)這個(gè)方法.而在IB中實(shí)例化就不需要實(shí)現(xiàn)它.
initWithNibName這個(gè)方法是在controller的類在IB中創(chuàng)建,但是通過Xcode實(shí)例化controller的時(shí)候用的.
awakeFromNib 這個(gè)方法是一個(gè)類在IB中被實(shí)例化是被調(diào)用的.看了帖子發(fā)現(xiàn)大家都推薦使用viewDidLoad而不要使用awakeFromNib,應(yīng)為 viewDidLoad會(huì)被多次調(diào)用,而awakeFromNib只會(huì)當(dāng)從nib文件中unarchive的時(shí)候才會(huì)被調(diào)用一次.實(shí)際測試中發(fā)現(xiàn),當(dāng)一個(gè) 類的awakeFromNib被調(diào)用的時(shí)候,那么這個(gè)類的viewDidLoad就不會(huì)被調(diào)用了,這個(gè)感覺很奇怪.
initWithCoder 是一個(gè)類在IB中創(chuàng)建但在xocdde中被實(shí)例化時(shí)被調(diào)用的.比如,通過IB創(chuàng)建一個(gè)controller的nib文件,然后在xocde中通過 initWithNibName來實(shí)例化這個(gè)controller,那么這個(gè)controller的initWithCoder會(huì)被調(diào)用.
awakeFromNib
當(dāng).nib文件被加載的時(shí)候缓淹,會(huì)發(fā)送一個(gè)awakeFromNib的消息到.nib文件中的每個(gè)對象,每個(gè)對象都可以定義自己的awakeFromNib函數(shù)來響應(yīng)這個(gè)消息塔逃,執(zhí)行一些必要的操作讯壶。也就是說通過nib文件創(chuàng)建view對象是執(zhí)行awakeFromNib
viewDidLoad
當(dāng)view對象被加載到內(nèi)存是就會(huì)執(zhí)行viewDidLoad,所以不管通過nib文件還是代碼的方式創(chuàng)建對象都會(huì)執(zhí)行viewDidLoad