所有的移动操作系统都有个致命的缺点:app很容易受到打扰。比如一个来电或者锁屏会导致app进入后台甚至被终止。
还有很多其它类似的情况会导致app受到干扰,在app受到干扰时,会产生一些系统事件,这时UIApplication会通知它的delegate对象,让delegate代理来处理这些系统事件。
delegate可处理的事件包括:
(1)应用程序的生命周期事件(如程序启动和关闭);
(2)系统事件(如来电);
(3)内存警告等。
每次新建完项目,都有个带有“AppDelegate”字眼的类,它就是 UIApplication 的代理,AppDelegate默认已经遵守了 UIApplicationDelegate 协议,已经是 UIApplication 的代理。下面对 AppDelegate.m 中的代理方法作简要解释:
当应用程序启动完成时,系统自动调用相应的生命周期方法(包括-[AppDelegate application:didFinishLaunchingWithOptions:] 和-[AppDelegate applicationDidBecomeActive:]),如上图控制台输出第一个红框所示,当按下 home 键(模拟器是 command + shift +H)时,系统自动调用 -[AppDelegate applicationWillResignActive:] 和 -[AppDelegate applicationDidEnterBackground:] 方法。对应的代理方法已经在上述图解内给出。
至于在哪里设置 UIApplication 的代理,需要了解 IOS 程序的启动过程,这要从入口函数 main 函数说起。
main函数中执行了一个 UIApplicationMain 这个函数,下面对函数中的参数做详细分析。
首先是官方文档:
针对文档上所述,作简要解释(主要是翻译):
argc、argv:与 c/c++相似, 直接传递给UIApplicationMain进行相关处理即可。
principalClassName:指定应用程序类名(app的象征),该类必须是UIApplication(或子类)。如果为nil,则用UIApplication类作为默认值。
delegateClassName:指定应用程序的代理类,该类必须遵守UIApplicationDelegate协议。
UIApplicationMain 函数会根据 principalClassName 创建 UIApplication 对象,根据 delegateClassName 创建一个 delegate 对象,并将该 delegate 对象赋值给 UIApplication 对象中的 delegate 属性,接着会建立应用程序的Main Runloop(事件循环),进行事件的处理(首先会在程序完毕后调用delegate对象的application:didFinishLaunchingWithOptions:方法),程序正常退出时UIApplicationMain函数才返回。
UIApplicationMain 的底层实现可概括如下四点:
1. 创建 UIApplication;
2. 创建 UIApplication 代理对象,成为 UIApplication 代理;
3. 开启主运行循环,处理事件,可以让程序一直在运行;
4. 加载 info.plist 文件,判断有没有指定 main.stroyboard,如果指定,就会去加载。
掌握了上述知识后,对 IOS 程序的启动过程便会更加明朗,可用图示概括如下: