UIApplication Delegate和UIApplicationMain(程序完整启动过程)

一、UIApplication Delegate

1、基本介绍

所有的移动操作系统都有个致命的缺点:app很容易受到打扰。比如一个来电或者锁屏会导致app进入后台甚至被终止。

还有很多其它类似的情况会导致app受到干扰,在app受到干扰时,会产生一些系统事件,这时UIApplication会通知它的delegate对象,让delegate代理来处理这些系统事件。包括:

(1)应用程序的声明周期事件(如程序启动和关闭)

(2)系统事件(如来电)

(3)内存警告

作用:当被打断的时候,通知代理进入到后台。

2、代码

 1 #import "AppDelegate.h"
 2 
 3 @interface AppDelegate ()
 4 
 5 @end
 6 
 7 @implementation AppDelegate
 8 
 9 // 当应用程序启动完毕的时候就会调用(系统自动调用)
10 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
11     NSLog(@"didFinishLaunchingWithOptions");
12     return YES;
13 }
14 // 即将失去活动状态的时候调用(失去焦点, 不可交互)
15 - (void)applicationWillResignActive:(UIApplication *)application {
16     NSLog(@"WillResignActive");
17 }
18 // 应用程序进入后台的时候调用,一般在该方法中保存应用程序的数据, 以及状态。
19 - (void)applicationDidEnterBackground:(UIApplication *)application {
20     NSLog(@"DidEnterBackground");
21 }
22 // 应用程序即将进入前台的时候调用,一般在该方法中恢复应用程序的数据,以及状态
23 - (void)applicationWillEnterForeground:(UIApplication *)application {
24     NSLog(@"WillEnterForeground");
25 }
26 // 重新获取焦点(能够和用户交互)
27 - (void)applicationDidBecomeActive:(UIApplication *)application {
28     NSLog(@"DidBecomeActive");
29 }
30 //应用程序即将被销毁的时候会调用该方法,
31 //注:如果应用程序处于挂起状态(程序未处于运行状态,但也没有被结束,只是暂时冻结)的时候无法调用该方法
32 - (void)applicationWillTerminate:(UIApplication *)application {
33     NSLog(@"WillTerminate");
34 }
35 // 应用程序接收到内存警告的时候就会调用,一般在该方法中释放掉不需要的内存(大部分是图片缓存)
36 - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
37 {
38     NSLog(@"DidReceiveMemoryWarning");
39 }
40 @end

打开App时候调用

2016-04-29 18:13:10.814 4.29UIApplication Delegate[12099:1953043] didFinishLaunchingWithOptions

2016-04-29 18:13:10.835 4.29UIApplication Delegate[12099:1953043] DidBecomeActive

App进入后来的时候调用

2016-04-29 18:15:11.888 4.29UIApplication Delegate[12099:1953043] WillResignActive 

2016-04-29 18:15:12.457 4.29UIApplication Delegate[12099:1953043] DidEnterBackground

重新进入App时候调用

2016-04-29 18:15:54.764 4.29UIApplication Delegate[12099:1953043] WillEnterForeground 

2016-04-29 18:15:55.281 4.29UIApplication Delegate[12099:1953043] DidBecomeActive

二、UIApplicationMain

1、启动原理

程序打开后会先进入main函数,执行UIApplicationMain函数

代码如下:(在main.m中)

#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
//        
//    argc: 系统或者用户传入的参数个数
//    argv: 系统或者用户传入的实际参数
//        1.根据传入的第三个参数创建UIApplication对象
//        2.根据传入的第四个产生创建UIApplication对象的代理
//        3.设置刚刚创建出来的代理对象为UIApplication的代理
//        4.开启一个事件循环
    }
}

2、UIApplicationMain的底层实现:

(1)根据principalClassName提供类名,创建UIApplication对象

(2)创建UIApplicationDelegate对象,并且成为UIApplication对象代理,app.delegate = delegate

(3)开启一个主运行循环,处理事件,可以让程序保持运行

(4)加载info.plist,并且判断有没有指定main.storyboard,如果指定,就会去加载

3、程序启动的完整过程:

(1)执行main函数

(2)执行UIApplicationMain 函数

       创建UIApplication对象

       创建UIApplication的delegate对象

(3)根据Info.plist获得最主要storyboard的文件名,加载最主要的storyboard(有storyboard)

       创建UIWindow

       创建和设置UIWindow的rootViewController

       显示窗口

(3)delegate对象开始处理(监听)系统事件(没有storyboard)

       程序启动完毕的时候, 就会调用代理的didFinishLaunchingWithOptions方法

       需要手动在didFinishLaunchingWithOptions创建UIWindow

       创建和设置UIWindow的rootViewController

       显示窗口

代码如下(在AppDelegate.m中):

 1 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
 2     //创建窗口
 3     self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
 4     //加载storyBoard,后面的Main首字母是大写的!!
 5     //nil当作为参数的时候表示NSBundle mainBundle
 6     UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
 7     //通过storyBoard创建一个控制器
 8     UIViewController *viewController = [storyBoard instantiateInitialViewController];
 9     self.window.rootViewController = viewController;
10     //显示窗口
11     [self.window makeKeyAndVisible];
12     return YES;
13 }

注:手动创建storyBoard之前注意要删除Main

原文地址:https://www.cnblogs.com/hissia/p/5447374.html