IOS学习笔记37——ViewController生命周期详解

原创 2012年12月06日 06:32:57

在我之前的学习笔记中讨论过ViewController,过了这么久,对它也有了新的认识和体会,ViewController是我们在开发过程中碰到最多的朋友,今天就来好好认识一下它。ViewController是IOS开发中MVC模式中的C,ViewController是view的controller,ViewController的职责主要包括管理内部各个view的加载显示和卸载,同时负责与其他ViewController的通信和协调。在IOS中,有两类ViewController,一类是显示内容的,比如UIViewController、UITableViewController等,同时还可以自定义继承自UIViewController的ViewController;另一类是ViewController容器,UINavigationViewController和UITabBarController等,UINavigationController是以Stack的形式来存储和管理ViewController,UITabBarController是以Array的形式来管理ViewController。和Android中Activity一样,IOS开发中,ViewController也有自己的生命周期(Lifecycle)。

首先来看看View的加载过程,如下图:



从图中可以看到,在view加载过程中首先会调用loadView方法,在这个方法中主要完成一些关键view的初始化工作,比如UINavigationViewController和UITabBarController等容器类的ViewController;接下来就是加载view,加载成功后,会接着调用viewDidLoad方法,这里要记住的一点是,在loadView之前,是没有view的,也就是说,在这之前,view还没有被初始化。完成viewDidLoad方法后,ViewController里面就成功的加载view了,如上图右下角所示。

在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];
}
上述代码首先得到屏幕的frame,然后根据该frame生成了一个contentView,并指定当前ViewController的root view为contentView,然后生成了一个LevelView的自定义View并将它通过addSubview:方法添加到当前ViewController当中,完成view的初始化加载。

关于loadView方法的重写,官方文档中有一个明显的注释,原文如下:

Note: When overriding the loadView method to create your views programmatically, you should not call super. Doing so initiates the default view-loading behavior and usually just wastes CPU cycles. Your own implementation of the loadView method should do all the work that is needed to create a root view and subviews for your view controller.

意思是当通过代码方式去创建你自己的view时,在loadView方法中不应该调用super,如果调用[super loadView]会影响CPU性能。

接下来我们看看ViewController中的view是如何被卸载的:



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

小结一下:

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


加入我们的QQ群或微信公众账号请查看:Ryan's zone公众账号及QQ群


欢迎关注我的新浪微博和我交流:@唐韧_Ryan


版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tangren03/article/details/8264072

iOS开发中ViewController使用详解

一、前言 在之前的一片文章中已经介绍了 从iOS的第一个应用中能学习到哪些知识点 在那篇文章中主要介绍了一个iOS程序的启动过程和应用的几大对象,以及应用的生命周期,同时也介绍了应用中的控制器知...
  • susu79
  • susu79
  • 2017-02-15 09:25:41
  • 1701

自定义ViewController的转场动画

https://onevcat.com/2013/10/vc-transition-in-ios7/ 这是我的WWDC2013系列笔记中的一篇,完整的笔记列表请参看这篇总览。本文仅作为个...
  • jeffasd
  • jeffasd
  • 2016-10-27 13:13:47
  • 1324

ViewController 生命周期重要方法

ViewController生命周期的重要方法 loadView,viewDidLoad,didReceiveMemeryWarning
  • u013328868
  • u013328868
  • 2015-07-03 22:31:25
  • 415

ViewController的didReceiveMemoryWarning是在什么时候调用的?默认的操作是什么?

当程序接到内存警告时View Controller将会收到这个消息:didReceiveMemoryWarning 从iOS3.0开始,不需要重载这个函数,把释放内存的代码放到viewDidUnlo...
  • yuanyuan1314521
  • yuanyuan1314521
  • 2016-05-19 17:29:38
  • 957

ScrollView上添加多个ViewController

今天在搭建项目的时候碰到一个相对内容较多的页面,类似如下图片,产品图片、主要参数、交易条件都有内容。 碰到问题:在进行搭建时碰到Block传值阻塞问题,在其中 一个页面的viewWillAp...
  • XingXingRainLove
  • XingXingRainLove
  • 2016-09-07 10:01:51
  • 2483

ViewController详解

一、生命周期 当一个视图控制器被创建,并在屏幕上显示的时候。 代码的执行顺序 1、 alloc                              创建对象,分配空间 2、init (...
  • lpsoga
  • lpsoga
  • 2014-04-08 16:02:59
  • 557

iOS 获取当前正在显示的ViewController

适用范围,tabbar的子视图都是UINavigationController,其它情况可以根据情况调整 - (UIViewController *)getCurrentVC{ U...
  • u014600626
  • u014600626
  • 2016-11-25 09:35:56
  • 10073

iOS开发中ViewController的页面跳转和弹出模态

ViewController 页面跳转 从一个Controller跳转到另一个Controller时,一般有以下2种:  1、利用UINavigationController,调用pushView...
  • u010850094
  • u010850094
  • 2016-08-22 10:17:09
  • 1114

ViewController生命周期

按照执行顺序排列:1. initWithCoder:通过nib文件初始化时触发。2. awakeFromNib:nib文件被加载的时候,会发生一个awakeFromNib的消息到nib文件中的每个对象...
  • jie863230900
  • jie863230900
  • 2018-03-15 17:54:13
  • 14

UIViewController详解--Swift版本

UIViewController类详解: 通过Nib文件初始化 [objc] view plain copy init(nibName nib...
  • u012108436
  • u012108436
  • 2016-07-19 10:35:46
  • 2363
收藏助手
不良信息举报
您举报文章:IOS学习笔记37——ViewController生命周期详解
举报原因:
原因补充:

(最多只允许输入30个字)