一、视图控制器的生命周期
只要是对象,就有其生命周期。创建视图控制器无非就两种,一种是从nib文件中加载创建,一种是编码创建。
开始之前先来补补一下相关概念:
什么是归档、解档?
- 归档(也称对象序列化)就是通过某种格式把对象保存到本地文件,以便以后读回该对象的内容。
- 解档(也称读档)就是把归档的对象文件读成原来的对象的过程。
什么是nib文件?
- Nib文件是基于磁盘的资源文件,用于存储一或多个对象的快照。
- Nib文件是Interface Builder文档,即在IB中可视化编辑设计界面时,就是在编辑nib文件。
- 保存nib文件的时候,就是将该对象图进行归档,加载nib文件的时候,就是将对象图进行解档。
- 加载一个nib文件会使该文件中的对象被重新构造,从而将每个对象的磁盘表示转化为应用程序可以操作的内存对象。
nib文件的加载?
- 将nib文件从磁盘载入内存,有两种方法:NSBundle和UINib。
- 执行unarchive(解档)和initialize操作,该过程主要由NSCoding Protocol中的initWithCoder:(NSCoder *)decoder完成。
- 建立connections:Outlets和Actions。
- 调用awakeFromNib方法,首先要调用super的awakeFromNib方法,之后可以设置一些个性化的操作,以及一些无法在设计时设定的操作。
1. nib、storyboard文件中加载创建
控制器:
1 // ViewController.h 2 #import <UIKit/UIKit.h> 3 4 @interface ViewController : UIViewController 5 6 @end
1 // ViewController.m 2 #import "ViewController.h" 3 4 #define LKFunc NSLog(@"方法:%s", __func__); 5 @interface ViewController () 6 7 @end 8 9 @implementation ViewController 10 11 #pragma mark - 1. 类加载 12 + (void)load { 13 LKFunc 14 } 15 16 #pragma mark - 2. 执行类第一个方法前调用 17 + (void)initialize { 18 LKFunc 19 } 20 21 #pragma mark - 3. nib文件解档初始化 22 - (instancetype)initWithCoder:(NSCoder *)aDecoder { 23 LKFunc 24 return [super initWithCoder:aDecoder]; 25 26 } 27 28 #pragma mark - 4. nib文件解档对象的个性化设置 29 - (void)awakeFromNib { 30 [super awakeFromNib]; 31 LKFunc 32 } 33 34 #pragma mark - 5. 加载视图 35 - (void)loadView { 36 [super loadView]; 37 LKFunc; 38 } 39 40 #pragma mark - 6. 视图加载完毕,视图个性化设置 41 - (void)viewDidLoad { 42 [super viewDidLoad]; 43 LKFunc 44 } 45 46 #pragma mark - 7. 视图即将显示 47 - (void)viewWillAppear:(BOOL)animated { 48 LKFunc 49 } 50 51 #pragma mark - 8. 视图即将为子视图布局 52 - (void)viewWillLayoutSubviews { 53 [super viewWillLayoutSubviews]; 54 LKFunc 55 } 56 57 #pragma mark - 9. 视图已经为子视图布局完毕 58 - (void)viewDidLayoutSubviews { 59 [super viewDidLayoutSubviews]; 60 LKFunc 61 } 62 63 #pragma mark - 10. 视图已经显示完毕 64 - (void)viewDidAppear:(BOOL)animated { 65 LKFunc 66 } 67 @end
运行结果:
2016-10-25 21:36:55.725 01-控制器的生命周期[7407:4478136] 方法:+[ViewController load] 2016-10-25 21:36:56.204 01-控制器的生命周期[7407:4478136] 方法:+[ViewController initialize] 2016-10-25 21:36:56.205 01-控制器的生命周期[7407:4478136] 方法:-[ViewController initWithCoder:] 2016-10-25 21:36:56.206 01-控制器的生命周期[7407:4478136] 方法:-[ViewController awakeFromNib] 2016-10-25 21:36:56.218 01-控制器的生命周期[7407:4478136] 方法:-[ViewController loadView] 2016-10-25 21:36:56.219 01-控制器的生命周期[7407:4478136] 方法:-[ViewController viewDidLoad] 2016-10-25 21:36:56.219 01-控制器的生命周期[7407:4478136] 方法:-[ViewController viewWillAppear:] 2016-10-25 21:36:56.226 01-控制器的生命周期[7407:4478136] 方法:-[ViewController viewWillLayoutSubviews] 2016-10-25 21:36:56.227 01-控制器的生命周期[7407:4478136] 方法:-[ViewController viewDidLayoutSubviews] 2016-10-25 21:36:56.232 01-控制器的生命周期[7407:4478136] 方法:-[ViewController viewDidAppear:]
注解:从实例可以看出对象的生命周期如以下顺序所示:
- initWithCoder 解档初始化,解档还原成视图对象
- awakeFromNib 还原完毕的对象可进行个性化设置
- loadView 加载显示视图对象,执行这个方法前会先调用view的getter方法,当获取不到视图对象时才调用此方法进行加载
- viewDidLoad 视图对象加载完毕,可进行个性化设置
- viewWillAppear 视图即将显示
- viewWillLayoutSubviews 视图即将为子视图布局
- viewDidLayoutSubviews 视图已经为子视图布局完毕
- viewDidAppear 视图已经显示完毕
此外,还有三个方法是视图对象生命周期的晚期:
9. viewWillDisappear: 视图即将消失
10. viewDidDisappear: 视图已经消失
11. dealloc 销毁对象释放内存
2. 编码创建
一般代码创建都是调用+alloc方法去申请内存空间创建对象,然后调用-init初始化。接下来的生命周期就跟上面的一样了,如下所示:
- loadView 加载显示视图对象,执行这个方法前会先调用view的getter方法,当获取不到视图对象时才调用此方法进行加载
- viewDidLoad 视图对象加载完毕,可进行个性化设置
- viewWillAppear 视图即将显示
- viewWillLayoutSubviews 视图即将为子视图布局
- viewDidLayoutSubviews 视图已经为子视图布局完毕
- viewDidAppear 视图已经显示完毕
此外,还有三个方法是视图对象生命周期的晚期:
7. viewWillDisappear: 视图即将消失
8. viewDidDisappear: 视图已经消失
9. dealloc 销毁对象释放内存