一瓷蛙、 大體流程:
(loadView/nib)文件來(lái)加view到內(nèi)存-->viewDidLoad函數(shù)進(jìn)一步初始化這些view-->內(nèi)存不足時(shí)厌衙, 調(diào)用viewDidUnload函數(shù)釋放views-->當(dāng)需要使用view時(shí)又回到第一步。
loadView:
永遠(yuǎn)不要主導(dǎo)調(diào)用這個(gè)函數(shù)勉盅。
viewController 會(huì)在view的property被請(qǐng)求并且當(dāng)前view值為nil時(shí)調(diào)用這個(gè)函數(shù)。如果你手動(dòng)創(chuàng)建view丢习, 你應(yīng)該重載這個(gè)函數(shù),切不要在重載的時(shí)候調(diào)用[super loadView]淮悼。viewDidLoad:
這個(gè)函數(shù)的作用主要是讓你可以進(jìn)一步的初始化你的views咐低。
viewDidLoad通常負(fù)責(zé)的是view及其子view被加載進(jìn)內(nèi)存之后的數(shù)據(jù)初始化的工作,即視圖的數(shù)據(jù)部分的初始化袜腥。viewDidUnLoad:
這個(gè)函數(shù)時(shí)viewDidLoad的對(duì)立函數(shù)见擦。在程序內(nèi)存欠缺時(shí),這個(gè)函數(shù)被controller調(diào)用羹令,來(lái)釋放他的view以及view相關(guān)的對(duì)象鲤屡。由于controller通常保存著view以及相關(guān)的object的引用,所以你必須使用這個(gè)函數(shù)來(lái)放棄這些對(duì)象的所有權(quán)以便內(nèi)存回收福侈,但不要釋放那些難以重建的數(shù)據(jù)酒来。viewWillAppear:
視圖即將可見(jiàn)時(shí)調(diào)用,默認(rèn)情況下不執(zhí)行任何操作肪凛。viewDidAppear:
視圖已完全過(guò)渡到屏幕上時(shí)調(diào)用堰汉。viewWillDisappear:
視圖被駁回時(shí)調(diào)用,覆蓋或以其他方式隱藏伟墙,默認(rèn)情況下不執(zhí)行任何操作翘鸭。viewDidDisappear:
視圖被駁回后調(diào)用,覆蓋或以其他方式隱藏远荠。默認(rèn)情況下不執(zhí)行任何操作矮固。didReceiveMemoryWarning:
當(dāng)程序內(nèi)存過(guò)度時(shí),系統(tǒng)會(huì)調(diào)用該方法譬淳。
二档址、Controller和View的生命周期
這里指的View是指Controller的View。它作為Controler的屬性邻梆,生命周期在Controller的生命周期內(nèi)守伸。就是說(shuō)你的Controller不能在view釋放前就釋放了。
當(dāng)你alloc并iit了一個(gè)ViewController時(shí)浦妄,這個(gè)ViewController應(yīng)該是還沒(méi)有創(chuàng)建view的尼摹。ViewController的view是使用了lazyInit方式創(chuàng)建,就是說(shuō)你調(diào)用的view屬性的getter:[self view]剂娄。在getter里會(huì)先判斷view是否創(chuàng)建蠢涝,如果沒(méi)有創(chuàng)建,那么會(huì)調(diào)用loadView來(lái)創(chuàng)建view阅懦。loadView完成時(shí)會(huì)繼續(xù)調(diào)用viewDidLoad和二。loadView和viewDidLoad的一個(gè)區(qū)別就是:loadView時(shí)還沒(méi)有view。而viewDidLoad時(shí)view以及創(chuàng)建好了耳胎。
當(dāng)view被添加其他view中之前時(shí)惯吕,會(huì)調(diào)用viewWillAppear惕它,而之后會(huì)調(diào)用viewDidAppear。
當(dāng)view從其他view中移出之前時(shí)废登,會(huì)調(diào)用viewWillDisAppear淹魄,而之后會(huì)調(diào)用viewDidDisappear。
當(dāng)view不在使用堡距,而且是disappeared甲锡,受到內(nèi)存警告時(shí),那么viewController會(huì)將view釋放并將其指向nil吏颖。
三搔体、代碼組織(如何設(shè)計(jì)良好的ViewController)
ViewController生命周期中有那么多函數(shù),一個(gè)重要問(wèn)題就是什么代碼該寫在什么地方半醉。
- init里不要出現(xiàn)創(chuàng)建view的代碼疚俱。良好的設(shè)計(jì),在init里應(yīng)該只有相關(guān)數(shù)據(jù)的初始化缩多,而且這些數(shù)據(jù)都是比較關(guān)鍵的數(shù)據(jù)呆奕。init里不要掉self.view,否則會(huì)導(dǎo)致viewcontroller創(chuàng)建view衬吆。(因?yàn)関iew是lazyinit的)梁钾。
- loadView中只初始化view,一般用于創(chuàng)建比較關(guān)鍵的view如tableViewController的tabView逊抡,UINavigationController的navgationBar姆泻,不可掉用view的getter(在掉super loadView前),最好也不要初始化一些非關(guān)鍵的view冒嫡。如果你是從nib文件中創(chuàng)建的viewController在這里一定要首先調(diào)用super的loadView方法拇勃,但建議不要重載這個(gè)方法。
- viewDidLoad 這時(shí)候view已經(jīng)有了孝凌,最適合創(chuàng)建一些附加的view和控件了方咆。
- viewWillAppear 這個(gè)一般在view被添加到superview之前,切換動(dòng)畫之前調(diào)用蟀架。在這里可以進(jìn)行一些顯示前的處理瓣赂。比如鍵盤彈出,一些特殊的過(guò)程動(dòng)畫(比如狀態(tài)條和navigationbar顏色)片拍。
- viewDidAppear 一般用于顯示后煌集,在切換動(dòng)畫后,如果有需要的操作捌省,可以在這里加入相關(guān)代碼苫纤。
- viewDidUnload 這時(shí)候viewController的view已經(jīng)是nil了。由于這一般發(fā)生在內(nèi)存警告時(shí),所以在這里你應(yīng)該將那些不在顯示的view釋放了方面。比如你在viewcontroller的view上加了一個(gè)label,而且這個(gè)label是viewcontroller的屬性色徘,那么你要把這個(gè)屬性設(shè)置成nil恭金,以免占用不必要的內(nèi)存,而這個(gè)label在viewDidLoad時(shí)會(huì)重新創(chuàng)建褂策。
- 接下來(lái)看看ViewController中的view是如何被卸載的:
當(dāng)系統(tǒng)發(fā)出內(nèi)存警告時(shí)横腿,會(huì)調(diào)用didReceiveMemoeryWarning方法,如果當(dāng)前有能被釋放的view斤寂,系統(tǒng)會(huì)調(diào)用viewWillUnload方法來(lái)釋放view耿焊,完成后調(diào)用viewDidUnload方法,至此遍搞,view就被卸載了罗侯。此時(shí)原本指向view的變量要被置為nil,具體操作是在viewDidUnload方法中調(diào)用self.myButton = nil;
小結(jié)
小結(jié)一下:loadView和viewDidLoad的區(qū)別就是溪猿,loadView時(shí)view還沒(méi)有生成钩杰,viewDidLoad時(shí),view已經(jīng)生成了诊县,loadView只會(huì)被調(diào)用一次讲弄,而viewDidLoad可能會(huì)被調(diào)用多次(View可能會(huì)被多次加載),當(dāng)view被添加到其他view中之前依痊,會(huì)調(diào)用viewWillAppear避除,之后會(huì)調(diào)用viewDidAppear。當(dāng)view從其他view中移除之前胸嘁,調(diào)用viewWillDisAppear瓶摆,移除之后會(huì)調(diào)用viewDidDisappear。當(dāng)view不再使用時(shí)缴渊,受到內(nèi)存警告時(shí)赏壹,ViewController會(huì)將view釋放并將其指向?yàn)閚il。
重要的事情在最后
ViewController的生命周期中各方法執(zhí)行流程如下:init—>loadView—>viewDidLoad—>viewWillApper—>viewDidApper—>viewWillDisapper—>viewDidDisapper—>viewWillUnload->viewDidUnload—>dealloc