iOS-控制器的生命周期

1. 控制器View的創(chuàng)建

首先我們來(lái)看一下控制器view創(chuàng)建的流程圖

從圖中我們可以看出,在控制器view加載過(guò)程中有兩個(gè)重要的方法loadView和viewDidLoad。下面我們來(lái)重點(diǎn)了解一下這兩個(gè)方法。

loadView方法

作用:loadView方法是用來(lái)負(fù)責(zé)創(chuàng)建UIViewController的view。首先判斷下有沒(méi)有指定storyboard或者xib,如果指定,就會(huì)加載它們描述的控制器的view,如果沒(méi)有指定,創(chuàng)建一個(gè)空的view。

什么時(shí)候調(diào)用:每次訪(fǎng)問(wèn)UIViewController的view,當(dāng)view為nil,就會(huì)調(diào)用loadView方法。

viewDidLoad

作用:一般我們會(huì)在這里做界面上的初始化操作,比如往view中添加一些子視圖等。

什么時(shí)候調(diào)用:每當(dāng)view創(chuàng)建完畢的時(shí)候,最終都會(huì)調(diào)用viewDidLoad方法。

其次,在view創(chuàng)建過(guò)程中還有一些需要注意的地方。

通過(guò)storyboard創(chuàng)建的控制器,或者通過(guò)xib創(chuàng)建的控制器的view,系統(tǒng)會(huì)幫我們加載控制器的view,具體內(nèi)部實(shí)現(xiàn)可以看iOS-UIWindow詳解,在此不在贅述

2.ViewController *vc = [[ViewController alloc]init];

底層也會(huì)調(diào)用-(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil方法。

(1).判斷下有沒(méi)有指定nibName,如果指定了,就會(huì)去加載指定的xib

(2).如果沒(méi)有指定,就會(huì)判斷下有沒(méi)有跟控制器類(lèi)名同名的xib,有,就會(huì)去加載

(3).判斷下有沒(méi)有跟控制器類(lèi)名同名的xib,但是后綴不帶Controller的xib,如果有,就會(huì)去加載

(4).如果沒(méi)有任何xib描述控制器的view,就不會(huì)加載xib。會(huì)創(chuàng)建一個(gè)顏色為clearColor的view。

2. 控制器View的生命周期

控制器View的生命周期方法

loadView:? ? ? ? ? ? ? ? ? ? ? ? 加載view

viewDidLoad:? ? ? ? ? ? ? ? ? view加載完畢

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

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

viewDidLayoutSubviews: 控制器的view布局子控件完成

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

viewWillDisappear:? ? ? ? 控制器的view即將消失的時(shí)候

viewDidDisappear:? ? ? ? 控制器的view完全消失的時(shí)候

view生命周期方法調(diào)用順序

viewDidLoad -> viewWillAppear -> viewWillLayoutSubviews -> viewDidLayoutSubviews -> viewDidAppear -> viewWillDisappear -> viewDidDisappear

3. 控制器View的延遲加載

控制器的view是延遲加載的:創(chuàng)建控制器并不一定會(huì)創(chuàng)建控制器的view,等用到時(shí)再加載

下面我們通過(guò)一個(gè)小的程序來(lái)驗(yàn)證一下

AppDelegate.m

- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {// Override point for customization after application launch.self.window = [[UIWindowalloc] initWithFrame:[UIScreenmainScreen].bounds];// 創(chuàng)建控制器,并一定會(huì)創(chuàng)建控制器的viewViewController *vc = [[ViewController alloc] init];? ? ? ? vc.view.backgroundColor = [UIColorredColor];self.window.rootViewController = vc;? ? ? ? [self.window makeKeyAndVisible];returnYES;}```ViewController.m

import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

// 自定義控制器的view

(void)loadView

{

NSLog(@"%s",func);

UIView *view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];

view.backgroundColor = [UIColor greenColor];

self.view = view;

}

// 控制器的view加載完成的時(shí)候調(diào)用

(void)viewDidLoad {

[super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

self.view.backgroundColor = [UIColor blueColor];

NSLog(@"%s",func);

}```

此時(shí)打印我們發(fā)現(xiàn)控制器的view顏色是紅色的,這是因?yàn)関iew的get方法底層中實(shí)現(xiàn)了loadView 和 viewDidLoad方法,loadView中將view設(shè)置為綠色,viewDidLoad方法中又將view設(shè)置成藍(lán)色,但是最后被vc.view.backgroundColor = [UIColor redColor];設(shè)置為紅色。

1.2 storyboard 間接實(shí)例化(initWithCoder)

當(dāng)你從 storyboard 初始化 ViewController 時(shí),iOS 會(huì)使用 initWithCoder,而不是 initWithNibName 來(lái)初始化這個(gè) ViewController,然后那個(gè) storyboard 會(huì)在自己內(nèi)部生成一個(gè) nib (storyboard 實(shí)例化 view / ViewController 時(shí),會(huì)把 nib 的信息放在 Coder 中,調(diào)用 initWithCoder)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容