視圖控制器對象的生命週期

視圖控制器UIViewController是我們程序中視圖和模型數據的紐帶,是MVC設計模式中的控制層,我們視圖的創建和數據的交互都是在UIViewController類或者其子類中進行的,我們何時何地去創建視圖和進行數據交互都跟它的生命週期息息相關。
當我們創建一個視圖控制器的時候,它的生命週期會涉及init、initWithNibName:bundle:、loadView、viewDidLoad、viewWillAppear、viewDidAppear、viewWillDisappear、viewDidDisappear、
didReceiveMemoryWarning、viewWillUnload、viewDidUnload這幾個方法。
在他們當中有存在一個關鍵的角色就是視圖控制器自身view視圖,所以如果能很清楚的瞭解視圖控制器view視圖的加載過程,就能夠明白視圖控制器的生命週期,所以這篇文章就圍繞這個view來理解視圖控制器的生命週期。
init和initWithNibName:bundle:方法:
我們可以通過兩種方式來實例化一個UIViewController,一個是init,另一個是initWithNibName:bundle:,如果我們通過init方法去實例化,執行init之後又會接着執行initWithNibName:bundle:方法去尋找有沒有可用的NIB文件,如果有就可以直接使用NIB文件的視圖控制器view視圖,如果沒有系統會調用loadView方法。在這個方法裏,我們可以初始化一些數據,但不要引用視圖控制器的view視圖,因爲這個時候view視圖還沒有創建。
loadView方法:
當程序進入到loadView方法中的時候,要做一個判斷,是自定義一個view視圖,還是不自定義,如果需要自己定義視圖,就可以實例化一個UIView傳遞給視圖控制器的view,如果不自定義,程序就會尋找有沒有Storyboard文件,如果有就使用,如果沒有系統會自動幫你創建一個空的視圖,這裏要注意一下,如果需要系統幫你創建,就需要調用[super  loadview],到現在我們雖然得到了視圖控制器的view,但是這個時候它是沒有放入內存的,只有這個方法執行完畢,程序會緊接着執行viewDidLoad,在執行viewDidLoadde 時候視圖控制器的view才被真正的創建。
viewDidLoad方法:
這個時候如果我們通過NIB、Storyboard、自定義、系統自動創建中任何一個方法創建視圖控制器的view視圖後,就可以接着執行viewDidLoad其他代碼,如果都沒有,如果去引用視圖控制器的view時,程序又會返回到loadView中去尋找這個view視圖,而我們的loadView中也沒有去創建,這時就會在loadView和viewDidLoad之間無限交替調用,我們的程序就會出錯。如果這個view在之前創建了,這個時候就可以調用視圖控制器的view視圖的getter方法,並且可以往它裏面添加子視圖了,這就是爲什麼一般添加子視圖的時候要在viewDidLoad方法裏進行了。
viewWillAppear方法:
這個方法是當我們的視圖控制器即將顯示的時候調用,這個時候我們可以恢復一些用戶數據,因爲內存警告時,如果這個視圖控制器沒有在當前窗口顯示,它的View就會被清除掉,下面會詳細說,所以當再次顯示的時候,我們需要恢復用戶的數據。
viewDidAppear方法:
這個方法是視圖控制器已經加載進來的時候調用。
viewWillDisappear方法:
這個方法是視圖控制器將要消失的時候調用,這個時候我們可以保存當前的用戶數據。
viewDidDisappear方法:
這個方法是視圖控制器已經消失的時候調用。
下面說一說視圖控制器的卸載:
didReceiveMemoryWarning、viewWillUnload、viewDidUnload方法:
當我們系統發出內存警告時會卸載沒有顯示在當前窗口的視圖控制器的View視圖,注意這裏只是卸載view視圖,而不會卸載視圖控制器。
在ios6.0之前系統會調用didReceiveMemoryWarning這個方法,然後去找已經創建的試圖控制器有沒有加載view視圖,如果已經加載,則會判斷這個view視圖是不是在當前窗口,如果不在當前窗口,就會先調用viewWillUnload方法告訴你這個視圖控制器的視圖即將被卸載掉,但是還沒有變成nil,這個時候你也可以保存用戶數據,防止數據丟失。這個方法執行完成之後會接着調用viewDidUnload方法,調用這個方法的時候不可見的視圖控制器的view視圖就release掉變成nil,這個時候需要你手動的把你加載到這個view中的子視圖清空,設爲nil。這個時候不顯示的試圖控制器的view視圖就成功卸載了,那當我在將這個視圖控制器的view再顯示在window上時會不會就什麼都沒有了呢?不會,應爲當你將這個視圖顯示出來的時候系統會重新加載一次,那是如何加載的呢?因爲當你顯示這個視圖的時候會調用這個view,如果系統找不到這個view就會又一次執行loadView方法,然後再執行viewDidload,視圖及其子視圖就會再一次加載進來。
ios6.0之後就沒有了viewWillUnload、viewDidUnload這兩個方法,而是讓我們自己判斷視圖是否在當前窗口,然後自己進行釋放,而且試圖控制器的view視圖也是要自己去釋放,系統不會自動爲你釋放,因此如果內存警告之後,你沒有去釋放,你的程序就可能閃退,然後崩潰掉。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章