谈谈AppDelegate

简介: 每个iOS程序都会有一个AppDelegate的类,这个类就是一个代理类,我们新建一个Project的时候,里面都会带有这个类。现在就让我们看看这个类。
前言

每个iOS程序都会有一个AppDelegate的类,这个类就是一个代理类,我们新建一个Project的时候,里面都会带有这个类。现在就让我们看看这个类。

开始介绍

对于AppDelegate,它的父类是UIResponder,然后实现了UIApplicationDelegate协议,这里的方法多是协议里面的方法,先看看默认的都有哪些方法。

1 application:didFinishLaunchingWithOptions:

它带参是这样的:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    return YES;
}
  1. 先看一下它的注释:在应用程序启动后,重写自定义点。这个是最直接的解释,一般在这里面,我做的操作如下:

    • 不用故事板,自定义rootview
    • 使用其他三方类库的时候在里面做一些初始化操作什么的。
  2. 参数

| 参数 | 描述 |
| ------------- | ---------------------------------------- |
| application | 你的app对象 |
| launchOptions | 一个指示app启动原因的字典(如果有)。这个字典也可能是空的在用户直接点击图标启动的情况下。例如当程序关闭,并且有推送消息过来的时候,通过点击推送打开app这个字典就包含推送过来的消息内容 |

  1. 返回值
    如果app不能处理URL资源或者继续用户活动,就会返回NO,否则返回YES。如果app是通过远程推送启动的,那么这个返回值会被忽略。
  2. 讨论
    使用这个方法(包括与其相关的application: willFinishLaunchingWithOptions: )用于完成app的初始化和一些微调。这个方法在状态复位的时候调用,但是发生在app的window和其他UI展现之前。在某些情况下,当这个方法返回值之后,系统会调用其他的代理方法。(当用户进入前台状态或者后台状态的情况)。

如果你没有在application: willFinishLaunchingWithOptions: 中处理launchOptions里面的key值,那么这个方法是你最后能够处理的地方。也就是说,你应该在这里对launchOptions里面的值提供合适的响应。

  1. 注意
    在UIApplicationDelegate中还有一个方法叫做:
- (void)applicationDidFinishLaunching:(UIApplication *)application;

当程序初始化的时候,强烈建议去使用:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    return YES;
}

or

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  return YES;  
}

那个applicationDidFinishLaunching:方法是个老版本iOS上使用的。

2 applicationWillResignActive:

它带参是这样的:

- (void)applicationWillResignActive:(UIApplication *)application {
}

告诉代理,app将要成为不活跃状态。

  1. 先看看它的自带的注释:当在程序将要从active状态到inactive状态的时候,会发(diao)送(yong)这个消(fang)息(fa)。这个发生的场景是程序被临时的打扰,例如打过来的电话或者是SMS信息。比如现在有电话进来,将会调用这个方法,还有就是有短信过来,然后你点击短信(3D touch)但是不进入程序的时候,也会去调用。或者是当用户退出程序,它开始转换到background state的时候。当app处于inactive状态的时候,它是继续运行的,但是不处理任何进来的事件响应。
  2. 讨论
    你应该使用这个方法去暂停正在进行的任务、禁用timers、减小OpenGLES 帧速率。游戏的话需要使用这个方法来暂停游戏。在将要到active状态或者background状态的时候,inactive状态的app应该做最少的工作。

如果app使用了没有保存的用户数据,你应该在这个方法里面保存它确保它不丢失。然而,苹果还是强烈建议在合适的时间去保存你的数据。千万不要依赖特定的app状态来保存用户的data。

3 applicationDidEnterBackground:

它带参数是这样:

- (void)applicationDidEnterBackground:(UIApplication *)application {
}

告诉代理,app当前已经处于background(后台)。

  1. 先看看它自带的注释:使用这个方法释放公共资源、保存用户数据、取消定时器。并尽量存储应用程序状态信息,这样万一应用程序被终止了,将来可以恢复到当前状态。如果app支持在后台运行,那么用户退出时会调用这个方法而不是applicationWillTerminate方法。
  2. 讨论
    除了这里面可以执行已经进入后台的操作,app还发出了一个UIApplicationDidEnterBackgroundNotification通知,因此如果有的类或者对象需要关注这个状态改变,可以去接收这个通知处理。
4 applicationWillEnterForeground:

它带参数是这样的:

- (void)applicationWillEnterForeground:(UIApplication *)application {
}

告诉代理,app将要进入前台。

  1. 先看看自带注释:这个方法会在应用程序从后台运行状态转换到活动状态的过程中被调用,可以在这里恢复应用程序正常运行所需信息。
  2. 讨论
    这里也有一个UIApplicationWillEnterForegrounNotification的通知。
5 applicationDidBecomeActive:

它带参数是这样的:

- (void)applicationDidBecomeActive:(UIApplication *)application {
}

告诉代理,app已经成为active状态。

  1. 先看看自带注释:重启应用程序在非活动状态时被站厅(或尚未启动)的任务。如果程序之前在后台运行,那么可以选择是否刷洗用户界面。
  2. 讨论
    当打电话的时候,程序会调用applicationWillResignAction:方法,当挂断电话之后,程序会调用此方法。

同样也有一个UIAppicationDidBecomeActiveNotification通知。

6 applicationWillTerminate:

它带参数是这样的:

- (void)applicationWillTerminate:(UIApplication *)application {
}

告诉代理方法,app将要终止。

  1. 先看看自带注释:程序将要终止时会调用该方法。尽可能保存需要的数据。
  2. 讨论
    这里面也有一个通知:UIApplicationWillTerminateNotification。
方法执行顺序

这里没有列出所有的方法,只是最常用的几个方法。
1 当我们第一次打开程序的时候,执行结果如下:

2016-11-08 17:56:57.670768 CategoriesDemo[3722:737434] application:didFinishLaunchingWithOptions:
2016-11-08 17:56:57.675868 CategoriesDemo[3722:737434] applicationDidBecomeActive:

2 当程序进入后台的时候,执行结果如下:

2016-11-08 17:59:46.082466 CategoriesDemo[3722:737434] applicationWillResignActive:
2016-11-08 17:59:46.607901 CategoriesDemo[3722:737434] applicationDidEnterBackground:

3 当程序进入前台的时候,执行结果如下:

2016-11-08 18:00:27.726073 CategoriesDemo[3722:737434] applicationWillEnterForeground:
2016-11-08 18:00:28.143117 CategoriesDemo[3722:737434] applicationDidBecomeActive:

4 当有电话进来的时候(程序在前台的时候),执行结果如下:

2016-11-08 18:03:29.891976 CategoriesDemo[658:224868] applicationWillResignActive:

5 当挂掉电话的时候,执行结果如下:

2016-11-08 18:03:35.344466 CategoriesDemo[658:224868] applicationDidBecomeActive:

这里插一句:也就是当程序在前台的时候,来电话,会执行applicationWillResignActive:方法。当电话挂掉时候,就会执行applicationDidBecomeActive:方法。

总结

1 应用程序运行状态有以下几种:

  • Not running (app没有启动或者已经启动但是被系统终结)
  • Inactive(app在前台,但是当前没有接收事件)
  • Active (app正在前台运行并且接收事件)
  • Background (app在后台,执行代码)
  • Suspended (app在后台,但是没有执行的代码)
    1348823833_6296.png
参考链接

1 https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html

相关文章
|
9月前
|
中间件 开发工具 数据库
AppDelegate模块化历程
AppDelegate控制着App的主要生命周期,比如App初始化完成后构建主视图,App接收到远程消息回调,Url-Scheme回调,第三方SDK初始化,数据库初始化等等。 基于这个原因,随着App的版本迭代,AppDelegate中的代码量会越来越大。当AppDelegate的代码量到达一定程度时,我们就该开始考虑将AppDelegate中的代码进行模块化封装。
56 0
|
iOS开发
SwiftUI极简教程06:代码优雅复用
SwiftUI极简教程06:代码优雅复用
417 0
SwiftUI极简教程06:代码优雅复用
|
编译器 iOS开发
iOS-底层原理 23:KVO 底层原理
iOS-底层原理 23:KVO 底层原理
137 0
iOS-底层原理 23:KVO 底层原理
|
iOS开发
UIWindow的讲述以及底层
UIWindow的讲述以及底层
105 0
UIWindow的讲述以及底层
|
设计模式 图形学
同事看了我的代码惊呼:居然是这么在Unity中用单例的
今天,同事问我:“在Unity中怎么用单例呀” 然后我就把我写的代码甩过去了。 同事:“哦,原来是这么用的,你来给我演示一下吧”
|
移动开发 JavaScript 前端开发
为什么我要编写自己的UIKit
如今的软件更像是由不计其数的砖块堆砌起来的金字塔,没有一点结构完整性,完全是成千上万的奴隶依靠蛮力修建起来。
262 0
为什么我要编写自己的UIKit
|
网络协议 API
从一个AFNetworking循环引用说起
本文分析使用代码是AFNetworking 3.2.1 最近使用Instruments中的Leaks分析项目内存泄露,发现了一个AFNetworking的循环引用。
1399 0
|
iOS开发
iOS-《编写高质量代码》笔记-第八章 定制init...和dealloc
建议50:了解对象的alloc 和 init... alloc 分配过程不仅进行对象的内存分配,还初始化对象的两个小而非常重要的属性,即它的isa实例变量和保持数。
995 0