1. 程式人生 > >iOS總結-UIViewController/UIView生命週期

iOS總結-UIViewController/UIView生命週期

參考: https://www.jianshu.com/p/d60b388b19f5

有關viewController的生命週期

storyBoard情況下的週期

非storyBoard下的週期

1.initWithNibName:bundle:
初始化UIViewController,執行關鍵資料初始化操作,非storyBoard建立UIViewController呼叫這個方法.
 不要在這裡做view相關操作,view在loadview方法中才初始化.

2. initWithCoder:  
使用storyBoard進行檢視管理,程式不會直接初始化一個UIViewController,storyBoard會自動初始化或在segue被觸發時自動初始化,因此方法initWithNibName:bundle:不會被呼叫,但是initWithCoder:會被呼叫.

3.awakeFromNib
當方法被呼叫時,所有檢視的outlet和action已經連線, 但還沒有被確定,這個方法可以算作適合檢視控制器的例項化配合一起使用的,因為有些需要根據使用者喜好進行設定的內容,無法存在stortboard或xib中,可以在此方法中被載入儘量.

4.loadView
當執行到loadView方法時,如果檢視控制器是通過nib建立,那麼檢視控制器已經從nib檔案中被解檔並建立好了,接下來任務就是對view進行初始化.

loadView方法是在UIViewController物件的view被訪問且為空的時候呼叫.這是它與awakeFromNib方法的一個區別.
假設我們在處理記憶體警告時釋放view屬性:self.view = nil. 因此loadView方法在檢視控制器的生命週期中可能被呼叫多次.

loadView方法不應該直接被呼叫,而是由系統呼叫.它會載入或建立一個view並把它賦值給UIViewController的view屬性.

在建立view的過程中, 首先會根據nibName去找對應的nib檔案然後載入.如果nibName為空或找不到對應的nib檔案,則建立一個空檢視,這種情況一般純程式碼.

注:在重寫loadView方法的時候,不要呼叫父類的方法.

5.viewDidLoad

當loadView將view載入記憶體中,會進一步呼叫viewDidLoad方法來進行進一步設定.此時,檢視層次已經放到記憶體中,通常,我們對於各種初始化資料的載入,初始化設定/修改約束/移除檢視等操作都可以在這個方法實現.

 檢視層次 (view hierachy): 因為每個檢視都有自己的子檢視,這個檢視層次其實也可以理解為一顆樹狀的資料結構.樹的根節點,也就是根檢視(root view), 在UIViewController中以view屬性. 它可以看做是其他所有子檢視的容器,也就是根節點.

6. viewWillAppear

系統載入所有資料後,將會在螢幕上顯示檢視,這時會先呼叫這個方法,通常我們會在這個方法對即將顯示的檢視做進一步的設定.如 設定裝置不同方向該如何顯示,設定狀態列方向/設定檢視顯示樣式.

    當APP有多個檢視時,上下級檢視切換是也會呼叫這個方法,如果在調入檢視時,需要對資料做更新,就只能在這個方法內實現.

7. viewWillLayoutSubviews  (將要佈局子檢視)

 view即將佈局其Subviews. 如view的bounds改變了(例如:狀態列從不顯示到顯示,檢視方法變化),要調整subviews的位置,在調整之前要做的工作可以放在該方法中實現.

8.viewDidLauoutSubviews
view已經佈局其Subviews, 這裡可以放置調整完成之後需要做的工作.

9.viewDidAppear
 在view被新增到檢視層級中以及多檢視,上下級檢視切換時呼叫這個方法,在這裡可以對正在顯示的檢視做設定.

10.viewWillDisappear
在檢視切換時,當前檢視在即將被移除/被覆蓋時,會呼叫該方法,此時還沒有呼叫removeFromSuperview.

11. viewDidDisappear
view已經消失/被覆蓋,此時已經呼叫removeFromSuperView.

12. dealloc
檢視被銷燬,此次需要對你在init和viewDidLoad中建立的物件進行釋放.

13.didReceiveMemoryWarning
在記憶體足夠的情況下,app檢視通常會一直儲存在記憶體中,如果記憶體不夠,會釋放掉自己擁有的檢視.系統只會釋放記憶體,不會釋放物件的所有權,通常我們需要在這裡將不需要顯示在記憶體中保留的物件釋放它的所有權,置為nil.

只有init系列的方法,如intiWithNibName:Bundle:需要自己呼叫,其他的loadView/awakeFromNib,是系統自動呼叫,viewDidLoad系列方法類似於回撥和通知,也會自動呼叫.

純程式碼寫檢視佈局時,要手動呼叫loadView方法,不能呼叫父類loadView. 純程式碼和xib僅存在於loadView方法及其之前,程式設計時需要注意的也就是loadView方法.

initWithNibName:bundle:  和 awakeFromNib 整個生命週期裡只會呼叫一次.

layoutSubViews方法由系統來呼叫,不能程式設計師來呼叫.可以呼叫setNeedsLayout進行標記,以保證UI下個刷屏系統中會呼叫layoutSubviews/layoutIfNeeded直接請求系統呼叫lauoutIfNeeded直接請求系統呼叫layoutSubviews.

layoutSubViews被呼叫時機:

1. addSubview會觸發, 多次觸發

2. view的frame改變/滾動UIScrollView/旋轉Screen/改變transform屬性

3.顯示在最前面的keywindow的UIView才會被呼叫.