首页 > 代码库 > iOS程序启动原理的理解
iOS程序启动原理的理解
应用的生命周期(从启动到退出):当用户点击应用图标之后,应用就开始启动。应用启动完成后,就会展示一系列的视图,和用户进行各种各样的交互(如滑动、点击)。当用户退出应用后,该应用就无法和用户进行交互。这一过程就是应用的生命周期体现。
在介绍应用启动过程及原理之前,先来了解一些概念以及其作用。
1、UIApplication
UIApplication对象是应用程序的象征,一个UIApplication对象就代表一个应用程序。每一个应用都有自己的UIApplication对象,而且是单例的,如果试图在程序中新建一个UIApplication对象,那么将报错提示。一个iOS程序启动后创建的第一个对象就是UIApplication对象,且只有一个。利用UIApplication对象,能进行一些应用级别的操作。可以参考这篇文章
2、UIApplication Delegate
所有的移动操作系统都有个致命的缺点:app很容易受到打扰。比如一个来电或者锁屏会导致app进入后台甚至被终止。还有很多其它类似的情况会导致app受到干扰,在app受到干扰时,会产生一些系统事件(iOS系统处理系统的事件的有限级别高于处理某个程序的事件),这时UIApplication会通知它的delegate对象,让delegate代理来处理这些系统事件。
所有UIApplicationDelegate的代理作用是当应用程序发出一系列系统事件时,做出相应的反应,也就是监听应用程序的状态变化如:进入、退出、程序间的调转。每次新建完项目,都有个带有“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函数是在创建项目的时候就已经写好了的,如下:
int main(int argc, char * argv[]) {
@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);</span>
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函数作用:
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、应用程序的状态
应用程序到这里就可以显示了。根据前面的应用程序代理功能的介绍,应用程序在启动过程中有以下几种状态:
1. Not running :应用还没有启动,或者应用正在运行但是途中被系统停止。
2. Inactive :当前应用正在前台运行,但是并不接收事件(当前 或许正在执行其它代码)。一般每当应用要从一个状态切换到另一个不同的状态时,中途过渡会短暂停留在此状态。唯一在此状态停留时间比较长的情况是:当用户 锁屏时,或者系统提示用户去响应某些(诸如电话来电、有未读短信等)事件的时候。
3. Active :当前应用正在前台运行,并且接收事件。这是应用正在前台运行时所处的正常状态。
4. Background :应用处在后台,并且还在执行代码。大多数将 要进入Suspended状态的应用,会先短暂进入此状态。然而,对于请求需要额外的执行时间的应用,会在此状态保持更长一段时间。另外,如果一个应用要 求启动时直接进入后台运行,这样的应用会直接从Not running状态进入Background状态,中途不会经过Inactive状态。比如没有界面的应用。注此处并不特指没有界面的应用,其实也可以是 有界面的应用,只是如果要直接进入background状态的话,该应用界面不会被显示。
5. Suspended :应用处在后台,并且已停止执行代码。系统自动 的将应用移入此状态,且在此举之前不会对应用做任何通知。当处在此状态时,应用依然驻留内存但不执行任何程序代码。当系统发生低内存告警时,系统将会将处 于Suspended状态的应用清除出内存以为正在前台运行的应用提供足够的内存。
iOS程序启动原理的理解