控制器的生命周期就是一些列的方法控制很多关于视图控制器如何随时间变化的操作;当事件发生时,会被发送至UIViewController,你的控制器是UIViewController的子类,如果你想知道事件何时发生,就要重写这些方法,不要忘记调用方法的超类;你需要知道如下消息,这样你的视图控制器的视图才能在iOS环境中正常运行:
- 你需要对控制进行初始化
- 你需要知道自己何时在屏幕出现和消失
- 你需要知道边界何时改变,你的几何变化
生命周期开始于创建,大部分视图控制器都是从storyboard中创建的,storyboard不会生成代码,你基本上是直接编辑对象(UIButton、UITextView),当保存storyboard时,他们像是冷冻干燥了,然后当程序运行时,水又回来,它们又活过来了。
viewDidLoad
- (void)viewDidLoad:(BOOL)animated; 初始化代码,输出口
-
适用范围
- 进入controller第一个调用的方法且一个周期只会被调用一次,主要放置控制器初始化代码(因为init不会在视图控制器中调用,所以可以把init全部内容放在这里)
-
限制条件
- 不要在viewDidLoad里添加任何视图形状的初始化信息 当viewDidLoad被调用的时候,视图边界还没有被确定,因为你还不知道程序竟会被运行在什么设备中或者是否被旋转。当它出现在屏幕上,也许不会出现在预定位置。
viewWillAppear
- (void)viewWillAppear:(BOOL)animated; 视图将要出现
- 适用范围
- 每次视图重新在屏幕上显示时,它都会被调用,调用的频率比较高。如果你需要执行的某些初始化基于某些数据,而这些数据可能在视图控制器视图离开屏幕时会发生变化(比如模型,最好同步model)在viewWillAppear对不可见时可能改变的内容进行同步
- 注意
- 不要添加一次性初始化的内容,这是viewDidLoad的责任。因为当应用有多个MVC时,它们会交替出现消失,所有viewWillAppear会被多次调用。
- 添加代码实现优化 如果你添加的操作需要大量资源,比如你要在viewDidLoad进行网络操作而且你的MVC始终没有出现在屏幕上,那viewDidLoad中的网络调用就浪费了时间。而在viewWillAppear上做些花销大的操作是值得的,因为视图就要在屏幕上显示
- 可以初始化视图大小 这里视图的几何信息已经确定 但是几何内容是可以在viewWillAppear之后改变的,比如屏幕的旋转,但是旋转后并不会调用viewWillAppear,但是视图几何信息已经改变了,只能用其它方法
viewWillDisappear
- (void)viewWillDisappear:(BOOL)animated; 视图将要消失
- 适用范围
- 暂停一些耗时操作(比如停止动画);少占用内存空间和CPU性能;很适合停止某项操作 记住当前状态 以便在vieWillAppear中恢复
will对应的did已完成的版本方法
- (void)viewDidAppear:(BOOL)animated;
- (void)viewDidDisappear:(BOOL)animated;
view{Will,Did}LayoutSubviews
- (void)view{Will,Did}LayoutSubviews; iOS6新出的当frame改变时调用的方法
- 使用场景
- 当view的frame改变的时候会调用,当旋转手机,几何布局就会改变
- 自动旋转相关
shouldAutorotate
返回YESsupportedInterfaceOrientations
返回一个新的方向(横/竖屏) 需要设置支持的方向
didReceiveMemoryWarning
内存不足,发生内存警告时会调用
-
使用场景
- 在内存不足的情况下,视图控制器会收到这个信息 内存不足不代表你的应用占了很大内存,也许是手机上运行了太多应用剩下的可用内存不多,需要释放一些空间,系统也许像很多应用发送了这个消息,是否生成这个警告完全由系统决定
- 收到警告,唯一要做的是试着释放内存(堆中的内容)即将强指针置为nil;展示图片、播放音频会占用很大的内存
-
为什么要避免成为内存大户(图像、视频、音频)
- 如果系统认为你的应用占用了很多内存,系统可以终止你的应用,从而造成程序的闪退,如果你合理使用内存,系统绝不会那样
- 用户切换其他应用时,希望得到同样多的内存,以便能流畅的运行,如果用户每次运行你的应用,其他应用就卡的不行,用户对你的app所占的内存有一个不好的印象,他们就会在应用商城AppStore差评你的app
awakeFromNib
从storyboard获取任何元素包括controller;Nib是延续以前的名称,你可以理解为awakeFromStoryboard
- 使用场景
- 获取storyboard的view元素
- 一般来说这里可以实现初始化内容,但是这个时候你的输出口还没有设好,所以初始化代码最好放在viewDidLoad中。但是如果无法将某些初始化操作放到viewDidLoad中执行,这时你可以放在awakeFromNib中
- 如果界面更复杂:用alloc/init来创建你的视图控制器,init并不是视图控制器的指定初始化方法,但init可以调用指定初始化方法,如下初始化模板:
eg.初始化模板
-(void) setup{}; //做一些无法在viewDidLoad中执行的操作
- (void)awakeFromNib { [self setup]; } //调用setup
// UIViewController指定初始化方法
- (instancetype)initWithNibName:(NSString *)name bundle:(NSBundle *)bundle
{
self = [super initWithNibName:name bundle:bundle];
[self setup]; //调用setup
return self;
}
PS:其实使用viewDidload也足够了