iOS生命周期

APP的启动流程

  1. 执行main函数

  2. 调用UIApplicationMain函数

  3. 初始化UIApplication对象并设置UIApplication类的代理

  4. UIApplication对象无限循环直至退出程序

UIApplication的生命周期

App有五种状态:

  • Not running(未运行):程序未启动

  • Inactive(未激活):其他两个状态切换时出现的短暂状态。唯一在此状态停留时间比较长的情况是:当用户锁屏时或者系统提示用户去响应Alert窗口(如来电、信息)时

  • Active(激活):在屏幕上显示的正常运行状态,该状态下可以接收用户输入并更新显示

  • Background(后台):程序在后台且能执行代码。用户按下Home键不久后进入此状态(先进入了Inactive状态,再进入Background状态),然后会迅速进入挂起状态(Suspended)。有的程序经过特殊的请求后可以长期处于Background状态

  • Suspended(挂起):程序在后台不能执行代码。普通程序在进入Background状态不久后就会进入此状态。当挂起时,程序还是停留在内存中的,当系统内存低时,系统就把挂起的程序清除掉,为前台程序提供更多的内存

  1. 首次打开APP时(或者无后台情况下打开APP)会调用如下函数:
1
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions;
  1. 然后调用如下函数:
1
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions;

此处有一个简化版的不带options的函数:

1
- (void)applicationDidFinishLaunching:(UIApplication *)application;

这个函数现在已经deprecated,如果实现了上面带options的函数则这个函数不会运行,否则会运行这个函数。

  1. 然后调用- (void)applicationDidBecomeActive:(UIApplication *)application;进入APP的UI界面,进入活跃状态(active),此时应用进入前台,可以用来恢复UI;

  2. 双击Home键(或等价操作),会调用- (void)applicationWillResignActive:(UIApplication *)application;,表示进入非活动(inactive)状态,此时应用准备进入后台(一般是处于多任务模式或者进入后台前的动画的那一段时间),可以用来保存UI;

  3. 如果接到电话或者进入Siri等情况下,会调用- (void)applicationWillResignActive:(UIApplication *)application;进入非活动状态;

  4. 按下Home键(或等价操作),会先调用- (void)applicationWillResignActive:(UIApplication *)application;,再调用- (void)applicationDidEnterBackground:(UIApplication *)application;,表面应用进入后台,这个阶段可以用来保存数据;

  5. 在多任务模式下点击应用,或者直接点击应用图标开启已经在后台的应用,会先调用- (void)applicationWillEnterForeground:(UIApplication *)application;,再调用- (void)applicationDidBecomeActive:(UIApplication *)application;进入活跃状态,applicationWillEnterForeground函数内可以用于恢复用户数据;

  6. 手动将APP从后台清除的时候会调用- (void)applicationWillTerminate:(UIApplication *)application;,此时可以保存用户数据;

  7. 当发生内存不足的时候,会调用- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application;,如果此时系统强制kill这个APP或者用户直接删除这个App则不会调用- (void)applicationWillTerminate:(UIApplication *)application;。

UIViewController的生命周期

默认的顺序为:

  1. + (void)load;,这个函数在引入当前类的时候就会调用(在applicationWillFinishLaunchingWithOptions之前;

  2. - (void)viewDidLoad;

  3. - (void)viewWillAppear:(BOOL)animated;

  4. - (void)viewWillLayoutSubviews;,这个函数在每一次发生bounds变化的时候都会调用,默认实现为空;

  5. - (void)viewDidAppear:(BOOL)animated;

至此当前vc对应的view显示出来了;

如果此时直接关闭App,则不会调用disappear系列函数(不管是关后台还是只是进入后台),如果切View,则会有如下顺序:

  1. - (void)viewWillDisappear:(BOOL)animated;

  2. - (void)viewDidDisappear:(BOOL)animated;

initWithNibName:bundle和awakeFromNib函数则是在使用storyboard的时候才会调用。

UI数据的保存与恢复

要保存因为意外关闭的View和ViewController,需要首先在AppDelegate.h中覆写如下两个函数(返回YES即可):

1
2
3
4
5
6
7
8
- (BOOL)application:(UIApplication *)application shouldSaveSecureApplicationState:(NSCoder *)coder
{
return YES;
}
- (BOOL)application:(UIApplication *)application shouldRestoreSecureApplicationState:(NSCoder *)coder
{
return YES;
}

然后在要保存的ViewController类或者View类中实现这两个方法:

1
2
- (void)encodeRestorableStateWithCoder:(NSCoder *)coder;
- (void)decodeRestorableStateWithCoder:(NSCoder *)coder;

举例如下:

1
2
3
4
5
6
7
8
9
10
11
-(void)encodeRestorableStateWithCoder:(NSCoder *)coder
{
[coder encodeObject:UIImagePNGRepresentation(_imageView.image)
forKey:@"YourImageKey"];
[super decodeRestorableStateWithCoder:coder];
}
-(void)decodeRestorableStateWithCoder:(NSCoder *)coder
{
_imageView.image = [UIImage imageWithData:[coder decodeObjectForKey:@"YourImageKey"]];
[super encodeRestorableStateWithCoder:coder];
}

p.s. 调用顺序,第一张图为整个App运行过程中的顺序,第二张图为保存View和VC的具体过程

LifeCycle

saveui