这个默认的 iOS 程序就是从 main 函数开始执行的,但是在 main 函数中我们其实只能看到一个方法,这个方法内部是一个消息循环(相当于一个死循环),因此运行到这个方法 UIApplicationMain 之后程序不会自动退出,而只有当用户手动关闭程序这个循环才结束。我们看下这个方法定义:
这个方法有四个参数:
关于返回值,即便声明了返回值,但该函数也从不会返回。
也就是说当执行 UIApplicationMain 方法后这个方法会根据第三个参数 principalClassName 创建对应的 UIApplication 对象,这个对象会根据第四个参数 delegateClassName 创建 AppDelegate 并指定此对象为 UIApplication 的代理;同时 UIApplication 会开启一个消息循环不断监听应用程序的各个活动,当应用程序生命周期发生改变 UIApplication 就会调用代理对应的方法。
既然应用程序 UIApplication 是通过代理和外部交互的,那么我们就有必要清楚 AppDelegate 的 *** 作细节,在这个类中定义了生命周期的各个事件的执行方法:
简要说下我们不同的 *** 作,程序运行结果:
通过简单的 *** 作,大家对整个运行周期有了个大概的了解。再附上一张图,让大家有个清晰的认识:
总览 UIViewController 生命周期:
下面创建了一个 TestViewController 类,了解下整个过程:
TestViewController.m:
在 ViewController.m 中:
我们在创建 TestViewController 实例时,可以通过以下两种方法:
我们经常使用的是第二种创建方法,其实第二种方法默认实现了第一种的方法,只不过两个参数默认传的是 nil。
当 TestVeiwController 通过 xib 加载的时候,看下 viewDidLoad 之前发生了什么:
无 xib:
TestVeiwController 通过 storyboard 加载:
控制台输出:
我们可以看到通过 storyboard 实例化与 init 实例化在 loadView 方法调用之前走的是不同的方法。我们看下这几个方法的不同:
此方法发生在 nib 加载之前。
调用此方法进行 Controller 初始化,与 nib 加载无关。nib 的加载是懒加载,当 Controller 需要加载其视图时,才会加载此方法中指定的 nib。
可以看出该方法初始化的 Controller 不是从 nib 创建的。
此方法发生在 nib 加载期间。
所有 archived 对象的初始化使用此方法。nib 中存储的对象就是 archived 对象,所以此方法是 nib 加载对象时使用的初始化方法。
当从 nib 创建 UIViewController 时使用此方法。
此方法发生在 nib 中所有对象都已完全加载完之后。
如果 initWithCoder 是 unarchiving 开始,那此方法就是结束。
在此方法中创建视图。
我们可以通过下图来理解它的逻辑:
每次访问 view 时,就会调用 self.view 的 get 方法,在 get 方法中判断 self.view==nil ,不为 nil 就直接返回 view,等于 nil 就去调用 loadView 方法。loadView 方法会去判断有无指定 storyBord/Xib 文件,如果有就去加载 storyBord/Xib 描述的控制器 view,如果没有则系统默认创建一个空的 view,赋给 self.view。loadView 方法有可能被多次调用(每当访问 self.view 并且为 nil 时就会调用一次);
系统会自动为我们加载 view,我们完全没必要手动创建 view。
视图将要被展示的时候调用。
其调用的时机与视图所在层次有关。例如我们常用的 push 与 present *** 作改变了当前视图层次,都会触发此方法。
1、那么 UIAlertController 也是 present *** 作怎么没有触发呢?
因为 UIAlertController 在另一个 window 上,view 在自己所在的 window 中层次并没有改变,所以不会触发,同理在锁屏以及进入后台时也不会触发。
2、如果控制器 B 被展示在另一个控制器 A 的 popover 中,那么被展示的控制器 B 在消失后,控制器 A 并不会调用此方法。
官方原文:
例如我们使用的 addSubview 方法,如下:
AViewController.m 中:
当我们将 BViewController 从 AViewController 中移除后,并不会触发 AViewController 的 viewWillAppear 方法。
视图渲染完成后调用,与 viewWillAppear 配套使用。
这两个方法发生在 viewWillAppear 与 viewDidAppear 之间。
viewWillDisappear 与 viewDidDisappear 配套使用。
两个方法的调用时机同 viewWillAppear 和 viewDidAppear 道理相同。
这两个方法是收到内存警告时调用的。
在 iOS5 以及之前使用的方法,iOS6 及之后已经废弃。在收到内存警告时,在此方法中将 view 置为 nil
收到内存警告时,系统自动调用此方法,回收占用大量内存的视图数据。我们一般不需要在这里做额外的 *** 作。如果要自己处理一些额外内存,重写时需要调用父类方法,即 [super didReceiveMemoryWarning] 。
UIViewController 释放时调用此方法。UIViewController 的生命周期到此结束。
当我们重写此方法时,ARC 环境下不需要调用父类方法,MRC 环境下需要调用父类方法,即 [super dealloc] 。
本篇主要介绍了 APP 的生命周期,以及 UIViewController 的生命周期,对我们程序开发的过程有了更清晰的认识。
参考资料:
https://www.cnblogs.com/kenshincui/p/3890880.html
https://www.quora.com/Cocoa-API-What-is-the-difference-between-initWithCoder-initWithNibName-and-awakeFromNib-1
应用的生命周期方法一般写在AppDelegate中
第一次打开该界面的时候会调用,在这里一般用来做各种数据的初始化。(注意返回到该页面不会执行该方法,除非关闭该页面,重新打开才会执行该方法)
在上面的didload方法执行完毕之后,页面即将将要显示的时候会执行该方法,该方法也可以对数据来进行初始化。(即使是返回到该页面,也会执行该方法)
等页面加载完之后就执行的方法。
页面将要消失执行的方法
界面已经消失的时候执行的方法
有时系统会从app一种状态切换另一种状态来响应系统发生的事件。例如,当用户按下home键、电话打入、或其他中断发生时,当前运行的应用程序会切换状态来响应。应用程序的状态有以下几种:
大多数发生状态转换时都会调用 delegate 对象对应的方法来响应app的状态改变。下面汇总了 delegate 对象的所有方法,当app状态发生转换时,你可能会使用到它们。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)