当用户点击应用图标之后,应用就开始启动.应用启动完成后,就会展示一系列的视图,和用户进行各种各样的交互(如滑动,点击).当用户退出应用后,该应用就无法和用户进行交互.这一过程就体现了一个应用的生命周期(从启动到退出).这里只介绍应用程序的显示部分.
在介绍应用启动过程及原理之前,先来了解一些概念以及其作用.
1,UIApplication
UIApplication 对象是应用程序的象征,一个 UIApplication 对象就代表一个应用程序.每一个应用都有自己的 UIApplication 对象,而且是单例的,如果试图在程序中新建一个 UIApplication 对象,那么将报错提示.一个 iOS 程序启动后创建的第一个对象就是 UIApplication 对象,且只有一个.利用 UIApplication 对象,能进行一些应用级别的操作.可以参考 [ iOS 开发之 UIApplication 和 delegate ](http://blog.csdn.net/shxwork/article/details/50053489)
2,UIApplication Delegate
所有的移动操作系统都有个问题:APP很容易受到打扰.比如来电或者锁屏会导致APP进入后台甚至被终止.还有很多其它类似的情况会导致app受到干扰,在app受到干扰时,会产生一些系统事件,这时UIApplication会通知它的delegate对象,让delegate代理来处理这些系统事件.
UIApplication Delegate的作用是当应用程序发出一系列系统事件时,做出相应的反应.新建完项目,都有个带有"AppDelegate"字眼的类,它就是UIApplication的代理,AppDelegate默认已经遵守了UIApplicationDelegate协议,已经是UIApplication的代理.系统事件如程序降将要启动,程序启动完成,程序进入后台,程序进入前台,程序退出等.对应代理的方法如下:
/**
* 程序启动完成
*/
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
return YES;
}
/**
* 程序将要进入后台
*/
- (void)applicationWillResignActive:(UIApplication *)application
{ }
/**
* 程序进入后台
*/
- (void)applicationDidEnterBackground:(UIApplication *)application
{ }
/**
* 程序将要进入前台
*/
- (void)applicationWillEnterForeground:(UIApplication *)application
{ }
/**
* 程序进入前台
*/
- (void)applicationDidBecomeActive:(UIApplication *)application
{ }
/**
* 程序退出
*/
- (void)applicationWillTerminate:(UIApplication *)application
{ }
上面就是涉及到应用程序非常重要的两个概念,下面我们来介绍点击应用图标后,应用程序的启动.我们都知道,C 语言是从 main 函数开始执行代码的.OC 作为 C 语言的超集,当然也不例外.点击图标,开始执行 main 函数.iOS 项目中的 main 函数是在创建项目的时候就已经写好了的,如下:
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
UIApplicationMain 函数参数 可以看到 iOS 项目中的 main 函数执行了一个 UIApplicationMain 函数,所有我们的重点就是要连接 UIApplicationMain 在执行的时候都做了哪些事情.下面我们先来了解一下 UIApplicationMain 函数的参数
* @param argc 系统参数
* @param argv 系统参数
* @param nil 应用程序名称
* @param class] 应用程序代理名称
*/
UIApplicationMain(int argc, charchar *argv[], NSString *principalClassName, NSString *delegateClassName);
argc,argv:直接传递给 UIApplicationMain 进行相关处理即可 principalClassName:指定应用程序类名(app 的象征),该类必须是 UIApplication(或子类).如果为 nil, 则用 UIApplication 类作为默认值 delegateClassName:指定应用程序的代理类,该类必须遵守 UIApplicationDelegate 协议
UIApplicationMain 函数作用 main 函数中之是执行了 UIApplicationMain 函数,可以肯定的时候该函数一定很重要,但它的具体作用是什么呢, UIApplicationMain 函数会根据 principalClassName 创建 UIApplication 对象,根据 delegateClassName 创建一个 delegate 对象,并将该 delegate 对象赋值给 UIApplication 对象中的 delegate 属性 . 接着会建立应用程序的 Main Runloop(事件循环),进行事件的处理 (首先会在程序完毕后调用 delegate 对象的 application:didFinishLaunchingWithOptions: 方法). app 启动时会加载 Info.plist 文件,看是否指定了 main.storyboard,如果设置了就去加载 main.storyboard,那么加载 main.storyboard 时,系统会进行如下操作: 创建窗口 -> 加载 main.storyboard 并且加载 main.storyboard 中指定的控制器 -> 创建控制器成为窗口的根控制器,让窗口显示出来.
总结 UIApplicationMain 函数作用: argc: 系统或者用户传入的参数 argv: 系统或用户传入的实际参数 1. 根据传入的第三个参数,创建 UIApplication 对象 2. 根据传入的第四个产生创建 UIApplication 对象的代理 3. 设置刚刚创建出来的代理对象为 UIApplication 的代理 4. 开启一个事件循环(可以理解为里面是一个死循环)这个时间循环是一个队列(先进先出)先添加进去的先处理 5. 加载 Info.plist 文件,看是否指定了 main.storyboard,如果设置了就去加载 main.storyboard
3,UIWindow 的创建
UIWindow 是特殊的 UIView ,通常一个App中只有UIWindows,当程序启动完毕后,创建的第一个视图控件就是UIWindow,接着创建控制器的UIView,将控制器的View添加到UIWindow上,控制器的 UIView 就显示在屏幕上.注意 UIWindow 本身不做显示,是控制器的UIView做展示,UIWindow 会给视图分发事件.
如果应用程序设置了main.storyboard文件,并指定了初始化控制器,系统会自动创建UIWindow.如果没有指定main.storyboard文件,就必须手动去创建.
UIWindow 作用: 1.UIWindow 作为一个容器,容纳所有的 UIView 2.UIWindow 会其他事件消息传递给 UIWiew
4,控制器的创建
当 UIWindow 创建完成后,必须指定一个根控制器或者在 UIWIndow 上添加子视图,这样才能显示出来,用户才能看得到,因为前面提到过,UIWindow 本身不做显示.当指定了 UIWindow 的根控制器,该控制器的 view 会自动添加在 UIWindow 上,并显示出来.控制器的创建可以看 这篇文章
5,视图控制器 view 的创建
视图控制器就是控制器视图在屏幕上的显示,对于一个控制器来说也是不具备显示的,只有它的 view 才具有显示能力,所以创建完一个控制器的时候,要给它指定一个根视图.具体的控制器 view 的创建可以查看 这篇文章 .
6,应用程序的状态
应用程序到这里就可以显示了.根据前面的应用程序代理功能的介绍,应用程序在启动过程中有以下几种状态:
Not running : 应用还没有启动,或者应用正在运行但是途中被系统停止.
Inactive : 当前应用正在前台运行,但是并不接收事件(当前 或许正在执行其它代码).一般每当应用要从一个状态切换到另一个不同的状态时,中途过渡会短暂停留在此状态.唯一在此状态停留时间比较长的情况是:当用户 锁屏时,或者系统提示用户去响应某些(诸如电话来电,有未读短信等)事件的时候.
Active : 当前应用正在前台运行,并且接收事件.这是应用正在前台运行时所处的正常状态.
Background : 应用处在后台,并且还在执行代码.大多数将 要进入 Suspended 状态的应用,会先短暂进入此状态.然而,对于请求需要额外的执行时间的应用,会在此状态保持更长一段时间.另外,如果一个应用要 求启动时直接进入后台运行,这样的应用会直接从 Not running 状态进入 Background 状态,中途不会经过 Inactive 状态.比如没有界面的应用.注此处并不特指没有界面的应用,其实也可以是 有界面的应用,只是如果要直接进入 background 状态的话,该应用界面不会被显示.
Suspended : 应用处在后台,并且已停止执行代码.系统自动 的将应用移入此状态,且在此举之前不会对应用做任何通知.当处在此状态时,应用依然驻留内存但不执行任何程序代码.当系统发生低内存告警时,系统将会将处 于 Suspended 状态的应用清除出内存以为正在前台运行的应用提供足够的内存.
来源: https://juejin.im/post/5a687e27f265da3e54693e8e