iOS 控制器的生命周期

一、 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将要出现

viewWillLayoutSubviewsViewController2

viewDidLayoutSubviewsViewController2

viewWillLayoutSubviews:ViewController1

viewDidLayoutSubviews:ViewController1

viewDidDisappear:ViewController1完全消失

viewDidAppear:ViewController2完全出现

小结:

-整个控制器声明周期:  viewDidLoad -> viewWillAppear -> viewWillLayoutSubviews -> viewDidLayoutSubviews ->  viewDidAppear -> viewWillDisappear -> viewDidDisappear

loadView()

若控制器有关联的 Nib 文件,该方法会从 Nib 文件中加载 view;如果没有,则创建空白 UIView 对象。

自定义实现不应该再调用父类的该方法。

viewDidLoad()

view 被加载到内存后调用viewDidLoad()。

重写该方法需要首先调用父类该方法。

该方法中可以额外初始化控件,例如添加子控件,添加约束。

该方法被调用意味着控制器有可能(并非一定)在未来会显示。

在控制器生命周期中,该方法只会被调用一次。

viewWillAppear(_:)

该方法在控制器 view 即将添加到视图层次时以及展示 view 时所有动画配置前被调用。

重写该方法需要首先调用父类该方法。

该方法中可以进行操作即将显示的 view,例如改变状态栏的取向,类型。

该方法被调用意味着控制器将一定会显示。

在控制器生命周期中,该方法可能会被多次调用。

注意:

如果控制器 A 被展示在另一个控制器 B 的 popover 中,那么控制器 B 不会调用该方法,直到控制器 A 清除。

viewWillLayoutSubviews()

该方法在通知控制器将要布局 view 的子控件时调用。

每当视图的 bounds 改变,view 将调整其子控件位置。

该方法可重写以在 view 布局子控件前做出改变。

该方法的默认实现为空。

该方法调用时,AutoLayout 未起作用。

在控制器生命周期中,该方法可能会被多次调用。

viewDidLayoutSubviews()

该方法在通知控制器已经布局 view 的子控件时调用。

该方法可重写以在 view 布局子控件后做出改变。

该方法的默认实现为空。

该方法调用时,AutoLayout 已经完成。

在控制器生命周期中,该方法可能会被多次调用。

viewDidAppear(_:)

该方法在控制器 view 已经添加到视图层次时被调用。

重写该方法需要首先调用父类该方法。

该方法可重写以进行有关正在展示的视图操作。

在控制器生命周期中,该方法可能会被多次调用。

viewWillDisappear(_:)

该方法在控制器 view 将要从视图层次移除时被调用。

类似 viewWillAppear(_:)。

该方法可重写以提交变更,取消视图第一响应者状态。

viewDidDisappear(_:)

该方法在控制器 view 已经从视图层次移除时被调用。

类似 viewDidAppear(_:)。

该方法可重写以清除或隐藏控件。

didReceiveMemoryWarning()

当内存预警时,该方法被调用。

不能直接手动调用该方法。

该方法可重写以释放资源、内存。

deinit

控制器销毁时(离开堆),调用该方法。

当屏幕旋转,view 的 bounds 改变,其内部的子控件也需要按照约束调整为新的位置,因此也调用了 viewWillLayoutSubviews() 和 viewDidLayoutSubviews()。

当在一个控制器内 Present 新的控制器,原先的控制器并不会销毁,但会消失,因此调用了viewWillDisappear和viewDidDisappear方法。

如果新的控制器 Dismiss,即清除自己,原先的控制器会再一次出现,因此调用了其中的viewWillAppear和viewDidAppear方法。

若 loadView() 没有加载 view,viewDidLoad() 会一直调用 loadView() 加载 view,因此构成了死循环,程序即卡死。

一、创建

1.alloc                                  创建对象,分配空间

2.init (initWithNibName) 初始化对象,初始化数据

3.loadView                          从nib载入视图 ,通常这一步不需要去干涉。除非你没有使用xib文件创建视图

4.viewDidLoad                  载入完成,可以进行自定义数据以及动态创建其他控件

5.viewWillAppear              视图将出现在屏幕之前,马上这个视图就会被展现在屏幕上了

6.viewDidAppear              视图已在屏幕上渲染完成

loadView方法

作用:loadView方法是用来负责创建UIViewController的view。首先判断下有没有指定storyboard或者xib,如果指定,就会加载它们描述的控制器的view,如果没有指定,创建一个空的view。

什么时候调用:每次访问UIViewController的view,当view为nil,就会调用loadView方法。

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

底层也会调用-(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil方法。

(1).判断下有没有指定nibName,如果指定了,就会去加载指定的xib

(2).如果没有指定,就会判断下有没有跟控制器类名同名的xib,有,就会去加载

(3).判断下有没有跟控制器类名同名的xib,但是后缀不带Controller的xib,如果有,就会去加载

(4).如果没有任何xib描述控制器的view,就不会加载xib。会创建一个颜色为clearColor的view。

控制器的view是延迟加载的:创建控制器并不一定会创建控制器的view,等用到时再加载

- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {

// Override point for customization after application launch.

self.window = [[UIWindowalloc] initWithFrame:[UIScreenmainScreen].bounds];

// 创建控制器,并一定会创建控制器的viewViewController *vc = [[ViewController alloc] init]; vc.view.backgroundColor = [UIColor redColor];

self.window.rootViewController = vc;

 [self.window makeKeyAndVisible];

returnYES;

}```

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加载完成的时候调用

(void)viewDidLoad {

[super viewDidLoad];

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

self.view.backgroundColor = [UIColor blueColor];

NSLog(@"%s",func);

}```

此时打印我们发现控制器的view颜色是红色的,这是因为view的get方法底层中实现了loadView 和 viewDidLoad方法,loadView中将view设置为绿色,viewDidLoad方法中又将view设置成蓝色,但是最后被vc.view.backgroundColor = [UIColor redColor];设置为红色。

- loadView

此时,控制器的 view 还未初始化,可以通过重写这个方法自定义控制器的 View,如果这样做,那就不能调用[super loadView]

- viewDidLoad

在控制器的生命周期中,它只会被调用一次,此时,view 已经初始化好,非常适合做一些页面的初始化任务。由于此时 view 的 bounds 尚未确定,所以不适合写 frame 类型的布局代码,但是给视图添加约束没有影响。

- viewWillAppear

它会在控制器的视图将要出现在屏幕中时被调用,在控制器生命周期中可能会被调用多次。在此处,适合做一些与视图出现相关联的任务,例如改变状态栏的方向、风格。

- viewWillLayoutSubviews

当 view 的子视图即将布局时,此方法会被调用,触发的条件是:

view 被添加到视图层次中

view 的 bounds 发生了改变

调用了- setNeedsLayout方法

调用了- layoutIfNeeded方法

这个方法是写 frame 布局代码的好地方,将 view 的子视图布局好,每次 view 大小发生改变时,其子视图布局也会相应改变。

- viewDidLayoutSubviews

当 view 的子视图已经布局时,此方法会被调用,触发条件同上。

- viewDidAppear

它会在控制器的视图出现在屏幕后被调用,此时,view 的 bounds 已经确定,不过在这里写布局相关代码,可能会反映到屏幕上。

- viewWillDisappear

视图即将从屏幕中消失时触发。

- viewDidDisppear

视图从屏幕中消失后触发。

/ 类的初始化方法

+ (void)initialize;

// 对象初始化方法

- (instancetype)init;

// 从归档初始化

- (instancetype)initWithCoder:(NSCoder *)coder;

// Xib初始化后

-(void)awakeFromNib;

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,539评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,594评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,871评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,963评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,984评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,763评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,468评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,850评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,002评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,144评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,823评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,483评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,026评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,150评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,415评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,092评论 2 355

推荐阅读更多精彩内容