每個ios開發者對loadView和viewDidLoad肯定都很熟悉,雖然這兩個函數使用上真的是非常簡單,但是和類似的initWithNibName/awakeFromNib/initWithCoder放在一起還是非常容易讓人混淆的.
一、loadView
永 遠不要主動調用這個函數。view controller會在view的property被請求并且當前view值為nil時調用這個函數。如果你手動創建view,你應該重載這個函數。如 果你用IB創建view并初始化view controller,那就意味著你使用initWithNibName:bundle:方法,這時,你不應該重載loadView函數。
這個方法的默認實現是這樣:先尋找有關可用的nib文件的信息,根據這個信息來加載nib文件,如果沒有有關nib文件的信息,默認實現會創建一個空白的UIView對象,然后讓這個對象成為controller的主view。
所以,重載這個函數時,你也應該這么做。并把子類的view賦給view屬性(property)(你create的view必須是唯一的實例,并且不被其他任何controller共享),而且你重載的這個函數不應該調用super。
如果你要進行進一步初始化你的views,你應該在viewDidLoad函數中去做。在iOS 3.0以及更高版本中,你應該重載viewDidUnload函數來釋放任何對view的引用或者它里面的內容(子view等等)。
這個網上的資料都說的很不全面,尤其是藍色字部分。
二、viewDidLoad
這個函數在controller加載了相關的views后被調用,而不論這些views存儲在nib文件里還是在loadView函數中生成。而多數情況下是做nib文件的后續工作。
網上資料對這個函數的描述則完全不對。
三、viewDidUnload
這 個函數是viewDidLoad的對立函數。在程序內存欠缺時,這個函數被controller調用,來釋放它的view以及view相關的對象。由于 controller通常保存這view以及相關object的引用,所以你必須使用這個函數來放棄這些對象的所有權以便內存回收。但不要釋放那些難以重 建的數據。
通常controller會保存nib文件建立的views的引用,但是也可能會保存著loadView函數創建的對象的引用。最完美的方法是使用合成器方法:
1
self.myCertainView = nil;
這樣合成器會release這個view,如果你沒有使用property,那么你得自己顯示釋放這個view。
網上對這個函數的描述含含糊糊,看了等于沒看。
四、結論
所以流程應該是這樣:
(loadView/nib文件)來加載view到內存 ——>viewDidLoad函數進一步初始化這些view ——>內存不足時,調用viewDidUnload函數釋放views
—->當需要使用view時有回到第一步
如此循環
需要厘清兩個概念,創建一個類和實例化一個類.在XCode中創建一個類和實例化一個類很容易區分,但是在IB(Interface Builder)中有時候就會迷糊.其實也很好區分,孤零零地創建了一個nib文件,沒有和其他可被實例化的類有直接或間接關系的時候,這個類或這些類 (一個nib文件俺也可能包含多個類)是沒有機會被實例化的,所以這種情況只是通過ib創建了一個類,而沒有實例化.真正的實例化還需要通過在Xcode 用代碼來讀取這個nib文件.知道這兩這的區別后這些方法也就容易辨認多了
viewDidLoad其實沒什么可混淆的,無論通過什么途徑加載(Xcode或者IB,這里的加載屬于實例化)完view后肯定會執行這個方法.
loadView需要分兩種情況.當你通過Xcode實例化一個類的時候就需要自己在controller中實現這個方法.而在IB中實例化就不需要實現它.
initWithNibName這個方法是在controller的類在IB中創建,但是通過Xcode實例化controller的時候用的.
awakeFromNib 這個方法是一個類在IB中被實例化是被調用的.看了帖子發現大家都推薦使用viewDidLoad而不要使用awakeFromNib,應為 viewDidLoad會被多次調用,而awakeFromNib只會當從nib文件中unarchive的時候才會被調用一次.實際測試中發現,當一個 類的awakeFromNib被調用的時候,那么這個類的viewDidLoad就不會被調用了,這個感覺很奇怪.
initWithCoder 是一個類在IB中創建但在xocdde中被實例化時被調用的.比如,通過IB創建一個controller的nib文件,然后在xocde中通過 initWithNibName來實例化這個controller,那么這個controller的initWithCoder會被調用.
awakeFromNib
當.nib文件被加載的時候,會發送一個awakeFromNib的消息到.nib文件中的每個對象,每個對象都可以定義自己的awakeFromNib函數來響應這個消息,執行一些必要的操作。也就是說通過nib文件創建view對象是執行awakeFromNib
viewDidLoad
當view對象被加載到內存是就會執行viewDidLoad,所以不管通過nib文件還是代碼的方式創建對象都會執行viewDidLoad