你的位置:首页 > 操作系统

[操作系统]iOS开发小功能之七: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 *)application37 {38   NSLog(@"DidReceiveMemoryWarning");39 }40 @end

打开App时候调用

2016-04-29 18:13:10.814 4.29UIApplication Delegate[12099:1953043] didFinishLaunchingWithOptions2016-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