iOS 控制器View加載順序詳細版

http://www.jianshu.com/p/e1ed4fe1f98c

 

加載過程:

1 一般情況下調用 init方法或者調用initWithNibName方法實例化UIViewController, 不管調用哪個方法都爲調用initWithNibName(方法定義如下)

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

2 接着會調用loadView方法來生成UIViewController.view

- (void)loadView

下面來簡單說下loadView底層

2.1.1.判斷下有沒有指定storyboard,如果有,就去加載storyboard描述的控制器的view
2.1.2.判斷下有沒有指定nibName,如果有,就去加載nibName描述的控制器的view

   - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil

如果判斷有沒有指定nibName,[self nibName]
2.1.3判斷下nibName是否爲空,如果爲空,他會嘗試找下有沒有跟控制器同名,但是不帶Controller的xib
2.1.4跟控制器同名的xib,nibName = ViewController,但是這一步有條件,前提條件你沒有重寫loadView
2.1.5如果都沒有找到,直接創建默認控制器的view

3 - (void)awakeFromNib;

這個方法用的時候,outlet還沒有連接起來,是view Controller剛從storyboard建的時候,沒有完全建好,不過可能有一些事情要在這個方法裏面完成,比如splitViewDelegate,需要在非常早期完成。然後調用 viewDidLoad方法
4 - (void)viewDidLoad

如果loadView不能生成UIViewController.view系統將會反覆調用loadView及viewDidLoad方法, 並且最終調用[super loadView] 方法返回UIViewController.view
然後依次調用如下2個方法, 這2個方法也十分重要, 在UINavigationController的POP操作後有時將要顯示的UIViewController中的View並沒有釋放(也有可能釋放掉) , UIViewController將不會調用上面的三個方法(initWithNibName,loadView,viewDidLoad) 而會調用下面這2個方法
5 - (void)viewWillAppear:(BOOL)animated;

6 - (void)viewDidAppear:(BOOL)animated;
緊接着調用下面兩個方法view中frame值佈局,使子控制器的frame值更加準確
7 - (void)viewWillLayoutSubviews
8 -(void)viewDidLayoutSubviews

9 卸載過程

- (void)viewWillDisappear:(BOOL)animated;
- (void)viewDidDisappear:(BOOL)animated;
- (void)viewWillUnload;//iOS5.0添加
- (void)viewDidUnload;
- (void)dealloc;

控制器View一些方法的區分

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中創建但在Xcode中被實例化時被調用的.比如,通過IB創建一個controller的nib文件,然後在xocde中通過initWithNibName來實例化這個controller,那麼這個controller的initWithCoder會被調用.
awakeFromNib 當.nib文件被加載的時候,會發送一個awakeFromNib的消息到.nib文件中的每個對象,每個對象都可以定義自己的awakeFromNib函數來響應這個消息,執行一些必要的操作。也就是說通過nib文件創建view對象是執行awakeFromNib

viewDidLoad 當view對象被加載到內存是就會執行viewDidLoad,所以不管通過nib文件還是代碼的方式創建對象都會執行viewDidLoad



文/_那有隻喵(簡書作者)
原文鏈接:http://www.jianshu.com/p/e1ed4fe1f98c
著作權歸作者所有,轉載請聯繫作者獲得授權,並標註“簡書作者”。
發佈了347 篇原創文章 · 獲贊 8 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章