UIViewCotroller中与其生命周期有关的几个函数如下:
//类的初始化方法
+ (void)initialize;
//对象初始化方法
- (instancetype)init;
//从归档初始化
- (instancetype)initWithCoder:(NSCoder *)coder;
//加载视图
-(void)loadView;
//加载视图完毕
- (void)viewDidLoad;
//将要布局子视图
-(void)viewWillLayoutSubviews;
//已经布局子视图
-(void)viewDidLayoutSubviews;
//内存警告
- (void)didReceiveMemoryWarning;
//已经展示
-(void)viewDidAppear:(BOOL)animated;
//将要展示
-(void)viewWillAppear:(BOOL)animated;
//将要消失
-(void)viewWillDisappear:(BOOL)animated;
//已经消失
-(void)viewDidDisappear:(BOOL)animated;
//挂起
-(void) viewDidUnload;
//被释放
-(void)dealloc;
ViewCotroller 总体的生命周期:
+ (void)initialize
{
if (self == [<#ClassName#> class]) {
<#statements#>
}
}
initialize函数并不会每次创建对象都调用,只有在这个类第一次创建对象时才会调用,做一些类的准备工作,再次创建这个类的对象,initalize方法将不会被调用,对于这个类的子类,如果实现了initialize方法,在这个子类第一次创建对象时会调用自己的initalize方法,之后不会调用,如果没有实现,那么它的父类将替它再次调用一下自己的initialize方法,以后创建也都不会再调用。因此,如果我们有一些和这个相关的全局变量,可以在这里进行初始化。
- (instancetype)init
{
self = [super init];
if (self) {
<#statements#>
}
return self;
}
init方法和initCoder方法相似,只是被调用的环境不一样,如果用代码进行初始化,会调用init,从nib文件或者归档进行初始化,会调用initCoder。
- (void)loadView
{
self.view = [[[UIWebView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame] autorelease];
}
每次访问UIViewController的view(比如controller.view、self.view)而且view为nil,loadView方法就会被调用,loadView方法是用来负责创建UIViewController的view, 自定义UIViewController的view.比如 UINavigationViewController 和 UITabBarController 等容器类的ViewController
ViewController 加载 View 过程
ViewController 卸载 View 过程
- (void) viewDidLoad
{
[super viewDidLoad];
}
1.系统调用
2.在view创建完毕后,最终都会调用viewDidLoad方法
3.一般我们会在这里做界面上的初始化操作,比如往view中添加一些子视图、从数据库或者网络加载模型数据装配到子视图中
- (void) didReceviveMemoryWarning
{
[super didReceviveMemoryWarning];
}
1.系统调用
2.当控制器收到内存警告时调用
3.去除一些不必要的内存,去除耗时的内存
4.调用viewDidUnload
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
viewWillAppear 总是在 viewDidLoad 之后被调用,但不是立即,当你只是引用了属性 view,却没有立即把 view 添加到任何已经展示的视图上时,viewWillAppear 不会被调用,这在 view 被外部引用时,就会发生。当然,随着 ViewController 的多次推入,多次进入子页面后返回,该方法会被多次调用。与 viewDidLoad 不同,调用该方法就说明控制器一定会显示。
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
//子视图有自定义动画时,建议在 Did 方法中启动
}
视图已在屏幕上渲染完成。子视图有自定义动画时,建议在 Did 方法中启动,在 Will
中启动动画时,动画效果将不会很理想.
在- (void)viewWillAppear:(BOOL)animated
和- (void)viewDidAppear:(BOOL)animated
之间会调用两个方法
- (void) viewWillLayoutSubviews
{
//该方法在通知控制器将要布局 view 的子控件时调用。每当视图的 bounds 改变,view 将调整其子控件位置。默认实现为空,可重写以在 view 布局子控件前做出改变。该方法调用时,AutoLayout 未起作用。
}
- (void)viewDidLayoutSubviews
�{
//该方法在通知控制器已经布局 view 的子控件时调用。默认实现为空,可重写以在 view 布局子控件后做出改变。该方法调用时,AutoLayout 未起作用。
}
注意:
使用 Autolayout 时,子视图大小只有在 viewDidLayoutSubviews 才真正被设置好,所以这里才是获取子视图大小的正确位置,常见的错误是,在 viewDidLoad 中读取了某个 view.frame,用来给其它子视图赋值,结果得到一堆大小“不定”的视图,甚至可能为零,在视图中看不见!
- (void)viewWillDisappear:(BOOL)animated
{
}
该方法在控制器 view 将要从视图层次移除时被调用,可重写以提交变更,取消视图第一响应者状态。
- (void)viewDidDisappear:(BOOL)animated
{
}
该方法在控制器 view 已经从视图层次移除时被调用,可重写以清除或隐藏控件。
- (void)viewWillDisappear:(BOOL)animated
和- (void)viewDidDisappear:(BOOL)animated
两者配套调用,具体指子视图控制器是以 push 和 present 方法显示的,父视图控制器的以上两个方法会被触发。特别的,addSubview 会调用子控制器 Appear 系列方法,但不会调用父视图 viewWillDisappear 方法。
- (void)viewDidUnload {
[super viewDidUnload];
self.name = nil;
self.pwd = nil;
}
1.如果当前UIViewController的view不在应用程序的视图层次结构(View Hierarchy)中,即view的superview为nil的时候,就会将view释放,并且调用viewDidUnload方法
所以一般在释放资源,主要是释放界面元素相关的资源,将相关的实例都赋值为nil
2.当再次访问UIViewController的view时,view已经在中被赋值为nil,所以又会调用loadView方法重新创建view
3.view被重新创建完毕后,还是会调用viewDidLoad方法进行界面元素的初始化
- (void) dealloc
{
}
dealloc方法只会在UIViewController被释放的时候调用,如果再次调用viewConroller,需要重新加载loadView和didLoadView
10.多个 ViewControllers 跳转时的生命周期
10.1 Push / Present
当我们点击 push 的时候首先会加载下一个界面然后才会调用界面的消失方法。
init:ViewController2
loadView:ViewController2
viewDidLoad:ViewController2
viewWillDisappear:ViewController1 将要消失
viewWillAppear:ViewController2 将要出现
viewWillLayoutSubviews ViewController2
viewDidLayoutSubviews ViewController2
viewWillLayoutSubviews:ViewController1
viewDidLayoutSubviews:ViewController1
viewDidDisappear:ViewController1 完全消失
viewDidAppear:ViewController2 完全出现
当在一个控制器内 Push / Present 新的控制器,原先的控制器并不会销毁,但会消失,因此调用了 viewWillDisappear 和 viewDidDisappear 方法。
10.2 Pop / Dismiss
如果控制器 A 被展示在另一个控制器 B 的 popover 中,那么控制器 B 不会调用 viewWillAppear 方法,直到控制器 A 清除。这时,控制器 B 会再一次出现,因此调用了其中的 viewWillAppear 和 viewDidAppear 方法。
In the end, refer to :
1.iOS开发笔记(八):UIViewController的生命周期
2.iOS对UIViewController生命周期和属性方法的解析
3.iOS开发之loadView、viewDidLoad及viewDidUnload的关系