1. 程式人生 > >ViewController加載順序與self.view

ViewController加載順序與self.view

views

技術分享

從Stroyboard和xib中加載的ViewController的不同點在於

1、從Storyboard加載的ViewController只調用initWithCoder:方法,從xib加載的ViewController調用的是先執行initWithNibName:方法,後執行init方法。如果使用initWithNibName:方法初始化,則不會執行init方法;

2、從Storyboard裏加載的ViewController,不能在initWithCoder:裏面寫self.view,而從xib裏面創建的ViewController可以這麽寫。

3、對於不帶xib的ViewController,只能使用init方法來進行初始化,使用initWithNibName:方法不能正常顯示。使用init方法初始化的順序如下:

log:

2014-12-26 15:36:07.857 St[269:9721] initWithNibName
2014-12-26 15:36:07.860 St[269:9721] init
2014-12-26 15:36:11.947 St[269:9721] viewDidLoad

2014-12-26 15:36:11.949 St[269:9721] viewWillAppear
2014-12-26 15:36:12.479 St[269:9721] viewDidAppear

*********************************

理論上,使用xib你的ViewController加載的順序是按照上面寫的順序一樣。沒錯,一點都沒有錯。

log:

2014-12-26 15:15:33.424 St[204:6297] initWithNibName
2014-12-26 15:15:33.431 St[204:6297] viewDidLoad
2014-12-26 15:15:33.432 St[204:6297] viewWillAppear

2014-12-26 15:15:33.966 St[204:6297] viewDidAppear

但是是,當你在initWithNibName方法裏面用到了self.view的話,那麽順序可能就會有所變化了。

技術分享

看一下log:

log:

2014-12-26 15:32:58.024 St[253:9015] initWithNibName
2014-12-26 15:32:58.025 St[253:9015] befroe self.view in init
2014-12-26 15:32:58.030 St[253:9015] viewDidLoad
2014-12-26 15:32:58.031 St[253:9015] after self.view in init

2014-12-26 15:32:58.034 St[253:9015] viewWillAppear

2014-12-26 15:32:58.565 St[253:9015] viewDidAppear

當我們用到self.view的時候,會優先執行loadView和viewDidLoad兩個方法,這兩個方法再執行剩下的init部分的操作(接下來就執行appear方法的內容,不再執行剛剛執行過的loadView和viewDidLoadView方法)。使用的過程當中還是要註意的。

(我去,辛苦做的內容,最後發現viewDidLoad方法的花括號把隊形打亂了。。。。。。

一、 ARC環境

  • 單個viewController的生命周期

    • initWithCoder:(NSCoder *)aDecoder:(如果使用storyboard或者xib)

    • loadView:加載view

    • viewDidLoad:view加載完畢

    • viewWillAppear:控制器的view將要顯示

    • viewWillLayoutSubviews:控制器的view將要布局子控件

    • viewDidLayoutSubviews:控制器的view布局子控件完成
      這期間系統可能會多次調用viewWillLayoutSubviews 、 viewDidLayoutSubviews 倆個方法

    • viewDidAppear:控制器的view完全顯示

    • viewWillDisappear:控制器的view即將消失的時候
      這期間系統也會調用viewWillLayoutSubviews 、viewDidLayoutSubviews 兩個方法

    • viewDidDisappear:控制器的view完全消失的時候

  • 多個viewControllers跳轉

    • 當我們點擊push的時候首先會加載下一個界面然後才會調用界面的消失方法

    • initWithCoder:(NSCoder *)aDecoder:ViewController2 (如果用xib創建的情況下)

    • loadView:ViewController2

    • viewDidLoad:ViewController2

    • viewWillDisappear:ViewController1 將要消失

    • viewWillAppear:ViewController2 將要出現

    • viewWillLayoutSubviews ViewController2

    • viewDidLayoutSubviews ViewController2

    • viewWillLayoutSubviews:ViewController1

    • viewDidLayoutSubviews:ViewController1

    • viewDidDisappear:ViewController1 完全消失

    • viewDidAppear:ViewController2 完全出現

  • 小結:
    -整個控制器聲明周期: viewDidLoad -> viewWillAppear -> viewWillLayoutSubviews -> viewDidLayoutSubviews -> viewDidAppear -> viewWillDisappear -> viewDidDisappear


二、非ARC環境下

  • didReceiveMemoryWarning:

    • 當app收到內存警告的時候會發消息給視圖控制器。

    • app從來不會直接調用這個方法,而是當系統確定可用內存不足的時候采取調用。

    • 如果你想覆寫這個方法來釋放一些控制器使用的額外內存,你應該在你的實現方法中調用父類的實現方法

  • viewWillUnload:(iOS6廢除)

    • 當消除掉控制器的視圖之前調用

    • 視圖不會再在低內存條件下被清除所以這個方法不會再被調用。

    • 在iOS5之前,當低的內存情況發生的時候,當前控制器的視圖們不再被需要的時候,系統會有選擇性的將這些視圖從這些內存移除。這個方法被調用的目的是在視圖被真正的銷毀前你可以執行一些清空的任務。比如,你想要使用這個方法去清空視圖的觀察者或通知或者記錄視圖的狀態以便當重新讀取的時候恢復。

    • 在iOS6之後,不再需要清空視圖的引用。因此,其他一些關於清理的方法,比如清空觀察者,也不是必要的了。

  • viewDidUnload:(iOS6廢除)

    • 當視圖從內存中被消除後調用

    • 視圖在地的內存情況下不再被銷毀所以這個方法也不再會調用

    • 在iOS5之前,地的內存狀況發生之後,當前的試圖控制器的視圖不再被需要,系統會選擇性的在視圖控制器的視圖被銷毀後調用。這個方法使你執行一些最後清空任務的最後機會如果你的視圖控制器存儲著對視圖的或子控件的單獨引用,你應該使用這個方法去釋放這些引用。你也可以使用這個方法去消除一些你再創建視圖時候所創建的但是當視圖不再的時候不再需要的關於對象的引用。你不應該使用這個方法去釋放用戶數據或者一些不能輕易被重新創建的數據。

    • 在iOS6之後,清空在試圖控制器中對views和其他對象的引用已經沒有必要了。

    • 當這個方法被調用的時候,視圖的屬性是空的。


ViewController加載順序與self.view