一、UIApplicationDelegate是什么?
每个 iPhone 应用程序都有一个 UIApplication,UIApplication 是 iPhone 应用程序的开始并且负责初始化并显示 UIWindow,并负责加载应用程序的第一个 UIView 到 UIWindow 窗体中。
UIApplication 的另一个任务是帮助管理应用程序的生命周期,而 UIApplication 通过一个名字为 UIApplicationDelegate 的代理类来履行这个任务。尽管 UIApplication 会负责接收事件,而 UIApplicationDelegate 则决定应用程序如何去响应这些事件,UIApplicationDelegate 可以处理的事件包括应用程序的生命周期事件(比如程序启动和关闭)、系统事件(比如来电、记事项警 告)。如下图:

通常是没必要修改UIApplication的,只需要知道 UIApplication 接收系统事件即可。处理系统事件需要编写一个继承自 UIApplicationDelegate 接口的类,而 UIApplicationDelegate 接口提供生命周期函数来处理应用程序以及应用程序的系统事件。我们新建项目的时候,往往会自动生成一个继承自 UIApplicationDelegate 接口的类AppDelegate。
二、UIApplicationDelegate的生命周期
下面通过一个小demo理解UIApplicationDelegate常用生命周期中的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #pragma mark 在应用程序加载完毕之后调用 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSLog(@"didFinishLaunchingWithOptions-加载完毕"); // 初始化一个窗口 self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; // 传入xib文件名来初始化一个控制器 self.viewController = [[[MJViewController alloc] initWithNibName:@"MJViewController" bundle:nil] autorelease]; // 设置窗口的根控制器 self.window.rootViewController = self.viewController; // 上面的代码内部执行了下面代码的操作 // [self.window addSubview:self.viewController.view]; // 窗口不会默认显示,需要调用方法来显示 // keyWindow是主窗口,只有主窗口才能跟用户正常交互 [self.window makeKeyAndVisible]; // self.window.hidden = NO; return YES; } #pragma mark 程序失去焦点的时候调用(不能跟用户进行交互了) - (void)applicationWillResignActive:(UIApplication *)application { NSLog(@"applicationWillResignActive-失去焦点"); } #pragma mark 当应用程序进入后台的时候调用(点击HOME键) - (void)applicationDidEnterBackground:(UIApplication *)application { NSLog(@"applicationDidEnterBackground-进入后台"); } #pragma mark 当应用程序进入前台的时候调用 - (void)applicationWillEnterForeground:(UIApplication *)application { NSLog(@"applicationWillEnterForeground-进入前台"); } #pragma mark 当应用程序获取焦点的时候调用 // 获取焦点之后才可以跟用户进行交互 - (void)applicationDidBecomeActive:(UIApplication *)application { NSLog(@"applicationDidBecomeActive-获取焦点"); } #pragma mark 程序在某些情况下被终结时会调用这个方法 - (void)applicationWillTerminate:(UIApplication *)application { NSLog(@"applicationWillTerminate-被关闭"); } |
项目启动后:
Test[517:c07] didFinishLaunchingWithOptions-加载完毕
Test[517:c07] applicationDidBecomeActive-获取焦点
按下home键:
Test[517:c07] applicationWillResignActive-失去焦点
Test[517:c07] applicationDidEnterBackground-进入后台
再按程序:
Test[517:c07] applicationWillEnterForeground-进入前台
Test[517:c07] applicationDidBecomeActive-获取焦点
三、UIViewController是什么
UIViewController(后面简称ViewController)是iOS开发中MVC模式中的C,ViewController是view的controller,ViewController的职责主要包括管理内部各个view的加载显示和卸载,同时负责与其他ViewController的通信和协调。
在IOS中,有两类ViewController,一类是显示内容的,比如UIViewController、UITableViewController等,同时还可以自定义继承自UIViewController的ViewController;另一类是ViewController容器,UINavigationViewController和UITabBarController等,UINavigationController是以Stack的形式来存储和管理ViewController,UITabBarController是以Array的形式来管理ViewController。和Android中Activity一样,IOS开发中,ViewController也有自己的生命周期。
四、UIViewController的生命周期
1、view的加载和卸载
既然ViewController负责管理内部各个view的加载显示和卸载,那我们先来看看View的加载过程,如下图:

从图中可以看到,在view加载过程中首先会调用loadView方法,在这个方法中主要完成一些关键view的初始化工作,比如UINavigationViewController和UITabBarController等容器类的ViewController;
接下来就是加载view,加载成功后,会接着调用viewDidLoad方法,这里要记住的一点是,在loadView之前,是没有view的,也就是说,在这之前,view还没有被初始化。完成viewDidLoad方法后,ViewController里面就成功的加载view了,如上图右下角所示。
在Controller中创建view有两种方式,一种是通过代码创建、一种是通过Storyboard或Interface Builder来创建,后者可以比较直观的配置view的外观和属性,Storyboard配合IOS6后推出的AutoLayout,应该是Apple之后主推的一种UI定制解决方案。
接下来我们看看ViewController中的view是如何被卸载的,如下图:

从图中可以看到,当系统发出内存警告时,会调用didReceiveMemoeryWarning方法,如果当前有能被释放的view,系统会调用viewWillUnload方法来释放view,完成后调用viewDidUnload方法,至此,view就被卸载了。此时原本指向view的变量要被置为nil,具体操作是在viewDidUnload方法中调用self.myView = nil;
2、ViewController的生命周期
ViewController的生命周期中各方法执行流程如下图:

例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
@interfaceViewController()
@end
@implementationViewController
-(instancetype)init
{
self=[superinit];
if(self){
NSLog(@"ViewController
初始化");
}
returnself;
}
-(instancetype)initWithCoder:(NSCoder
*)coder
{
self=[superinitWithCoder:coder];
if(self){
NSLog(@"ViewController
从归档初始化");
}
returnself;
}
-(instancetype)initWithNibName:(NSString
*)nibNameOrNilbundle:(NSBundle
*)nibBundleOrNil{
self=[superinitWithNibName:nibNameOrNilbundle:nibBundleOrNil];
if(self){
self.view.backgroundColor=[UIColorwhiteColor];
NSLog(@"ViewController
从xib初始化");
}
returnself;
}
-(void)loadView{
[superloadView];
NSLog(@"ViewController
开始加载视图");
}
-(void)viewDidLoad{
[superviewDidLoad];
NSLog(@"ViewController
已经加载视图");
}
-(void)viewWillLayoutSubviews{
[superviewWillLayoutSubviews];
NSLog(@"ViewController
开始布局子视图");
}
-(void)viewDidLayoutSubviews{
[superviewDidLayoutSubviews];
NSLog(@"ViewController
完成布局子视图");
}
-(void)viewWillAppear:(BOOL)animated{
[superviewWillAppear:animated];
NSLog(@"ViewController
即将显示");
}
-(void)viewDidAppear:(BOOL)animated{
[superviewDidAppear:animated];
NSLog(@"ViewController
已经显示");
}
-(void)viewWillDisappear:(BOOL)animated{
[superviewWillDisappear:animated];
NSLog(@"ViewController
即将消失");
}
-(void)viewDidDisappear:(BOOL)animated{
[superviewDidDisappear:animated];
NSLog(@"ViewController
已经消失");
}
-(void)didReceiveMemoryWarning{
[superdidReceiveMemoryWarning];
NSLog(@"ViewController
收到内存警告");
}
@end
|
打印结果:
|
2017-01-1112:02:55.422Test[11948:560350]ViewController从归档初始化
2017-01-1112:02:55.433Test[11948:560350]ViewController开始加载视图
2017-01-1112:02:55.434Test[11948:560350]ViewController已经加载视图
2017-01-1112:02:55.434Test[11948:560350]ViewController即将显示
2017-01-1112:02:55.440Test[11948:560350]ViewController开始布局子视图
2017-01-1112:02:55.440Test[11948:560350]ViewController完成布局子视图
2017-01-1112:02:55.443Test[11948:560350]ViewController已经显示
|