首页 > 代码库 > ViewController的生命周期分析和使用

ViewController的生命周期分析和使用

ViewController的生命周期分析和使用

一、结构


按结构可以对iOS的所有ViewController分成两类:
1、主要用于展示内容的ViewController,这种ViewController主要用于为用户展示内容,并与用户交互,如UITableViewControllerUIViewController
2、用于控制和显示其他ViewControllerViewController。这种ViewController一般都是一个ViewController的容器。如UINavigationControllerUITabbarController。它们都有一个属性:viewControllers

其中UINavigationController表示一种Stack式结构,push一个ViewControllerpop一次,因此后一个ViewController一般会依赖前一个ViewController。而UITabbarController表示一个Array结构,各个ViewController是并列的。

第一种ViewController会经常被继承,用来显示不同的数据给用户。而第二种很少被继承,除非你真的需要自定义它。
注:细心的同学应该能发现,在Xcode中新建一个ViewController时,只可以选择继承自UIViewControllerUITableViewController,而它们都是第一种。
1

二、ControllerView的生命周期

这里指的View是指ControllerView。它作为Controler的属性,生命周期在Controller的生命周期内。就是说你的Controller不能在view释放前就释放了。
2ViewController生命周期


当你allocinit了一个ViewController时,这个ViewController应该是还没有创建view的。ViewControllerview是使用了lazyInit方式创建,就是说你调用的view属性的getter:[selfview]。在getter里会先判断view是否创建,如果没有创建,那么会调用loadView来创建viewloadView完成时会继续调用viewDidLoadloadViewviewDidLoad的一个区别就是:loadView时还没有view。而viewDidLoadview以及创建好了
view被添加其他view中之前时,会调用viewWillAppear,而之后会调用viewDidAppear
view从其他view中移出之前时,会调用viewWillDisAppear,而之后会调用viewDidDisappear
view不在使用,而且是disappeared,受到内存警告时,那么viewController会将view释放并将其指向nil
三、代码组织(如何设计良好的viewcontroller

ViewController
生命周期中有那么多函数,一个重要问题就是什么代码该写在什么地方。

1init里不要出现创建view的代码。良好的设计,在init里应该只有相关数据的初始化,而且这些数据都是比较关键的数据。init里不要掉self.view,否则会导致viewcontroller创建view。(因为viewlazyinit的)。

2loadView中只初始化view,一般用于创建比较关键的viewtableViewControllertabViewUINavigationControllernavgationBar,不可掉用viewgetter(在掉superloadView前),最好也不要初始化一些非关键的view。如果你是从nib文件中创建的viewController在这里一定要首先调用superloadView方法,但建议不要重载这个方法。

3viewDidLoad这时候view已经有了,最适合创建一些附加的view和控件了。有一点需要注意的是,viewDidLoad会调用多次(viewcontroller可能多次载入view,参见图2)。

4viewWillAppear这个一般在view被添加到superview之前,切换动画之前调用。在这里可以进行一些显示前的处理。比如键盘弹出,一些特殊的过程动画(比如状态条和navigationbar颜色)。

5viewDidAppear一般用于显示后,在切换动画后,如果有需要的操作,可以在这里加入相关代码。

6viewDidUnload这时候viewControllerview已经是nil了。由于这一般发生在内存警告时,所以在这里你应该将那些不在显示的view释放了。比如你在viewcontrollerview上加了一个label,而且这个labelviewcontroller的属性,那么你要把这个属性设置成nil,以免占用不必要的内存,而这个labelviewDidLoad时会重新创建。

7接下来我们看看ViewController中的view是如何被卸载的:
从图中可以看到,当系统发出内存警告时,会调用didReceiveMemoeryWarning方法,如果当前有能被释放的view,系统会调用viewWillUnload方法来释放view,完成后调用viewDidUnload方法,至此,view就被卸载了。此时原本指向view的变量要被置为nil,具体操作是在viewDidUnload方法中调用self.myButton = nil;

小结一下:loadViewviewDidLoad的区别就是,loadViewview还没有生成,viewDidLoad时,view已经生成了,loadView只会被调用一次,而viewDidLoad可能会被调用多次(View可能会被多次加载),当view被添加到其他view中之前,会调用viewWillAppear,之后会调用viewDidAppear。当view从其他view中移除之前,调用viewWillDisAppear,移除之后会调用viewDidDisappear。当view不再使用时,受到内存警告时,ViewController会将view释放并将其指向为nil

ViewController
的生命周期中各方法执行流程如下:init—>loadView—>viewDidLoad—>viewWillApper—>viewDidApper—>viewWillDisapper—>viewDidDisapper—>viewWillUnload->viewDidUnload—>dealloc

ViewController的生命周期分析和使用