原文转自:http://blog.sina.com.cn/s/blog_702e40a80101czap.html
在我之前的学习笔记中讨论过ViewController,过了这么久,对它也有了新的认识和体会,ViewController是我们在开发过程中碰到最多的朋友,今天就来好好认识一下它。ViewController是IOS开发中MVC模式中的C,ViewController是view的controller,ViewController的职责主要包括管理内部各个view的加载显示和卸载,同时负责与其他ViewController的通信和协调。在IOS中,有两类ViewController,一类是显示内容的,比如UIViewController、UITableViewController等,同时还可以自定义继承自UIViewController的ViewController;另一类是ViewController容器,UINavigationViewControll
首先来看看View的加载过程,如下图:
从图中可以看到,在view加载过程中首先会调用loadView方法,在这个方法中主要完成一些关键view的初始化工作,比如UINavigationViewControll
在Controller中创建view有两种方式,一种是通过代码创建、一种是通过Storyboard或Interface Builder来创建,后者可以比较直观的配置view的外观和属性,Storyboard配合IOS6后推出的AutoLayout,应该是Apple之后主推的一种UI定制解决方案,后期我会专门介绍一篇使用AutoLayout进行UI制作的文章。言归正传,通过IB或Storyboard创建view,在Controller中创建view后,会在Controller中对view进行一些操作,会出现如下代码:
- @interface
MyViewController() - @property
(nonatomic) IBOutlet id myButton; - @property
(nonatomic) IBOutlet id myTextField; -
- -
(IBAction)myAction:(id)sender; - @end
这里用IBOutlet标记了一个UIButton和一个UITextField,用IBAction来标记UIButton的响应事件,IBOutlet和IBAction都是一个整形常量,用来标记控件,通过一张图能比较清晰的看清他们之间的关系:
上图中,MyViewController是继承自UIViewController的一个自定义ViewController,它包含两个View,一个是UIButton,一个是UITextField,从箭头的指向性上就可以比较好的理解IBOutlet和IBAction了。IBOutlet是告诉Interface Builder,此实例变量被连接到nib文件中的view对象,IBOutlet本身不做任何操作,只是一个标记作用。IBAction同样是个标记关键字,它只能标记方法,它告诉IB用IBAction标记的方法可以被某个控件触发。
通过编程的方式创建view,如下代码:
- -
(void)loadView - {
-
CGRect applicationFrame = [[UIScreen mainScreen] applicationFrame]; -
UIView *contentView = [[UIView alloc] initWithFrame:applicationFrame]; -
contentView.backgroundColor = [UIColor blackColor]; -
self.view = contentView; -
-
levelView = [[LevelView alloc] initWithFrame:applicationFrame viewController:self]; -
[self.view addSubview:levelView]; - }
关于loadView方法的重写,官方文档中有一个明显的注释,原文如下:
Note: loadView
super
. Doing so initiates the default view-loading behavior and usually just wastes CPU cycles. Your own implementation of the loadView
意思是当通过代码方式去创建你自己的view时,在loadView方法中不应该调用super,如果调用[super loadView]会影响CPU性能。
接下来我们看看ViewController中的view是如何被卸载的:
从图中可以看到,当系统发出内存警告时,会调用didReceiveMemoeryWarning
小结一下:
loadView和viewDidLoad的区别就是,loadView时view还没有生成,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