iOS UIApplicationDelegate 与 UIViewController 生命周期

1,023 阅读6分钟

一、UIApplicationDelegate是什么?

每个 iPhone 应用程序都有一个 UIApplication,UIApplication 是 iPhone 应用程序的开始并且负责初始化并显示 UIWindow,并负责加载应用程序的第一个 UIView 到 UIWindow 窗体中。

UIApplication 的另一个任务是帮助管理应用程序的生命周期,而 UIApplication 通过一个名字为 UIApplicationDelegate 的代理类来履行这个任务。尽管 UIApplication 会负责接收事件,而 UIApplicationDelegate 则决定应用程序如何去响应这些事件,UIApplicationDelegate 可以处理的事件包括应用程序的生命周期事件(比如程序启动和关闭)、系统事件(比如来电、记事项警 告)。如下图:

1933920-acb1107656c1a483

 

通常是没必要修改UIApplication的,只需要知道 UIApplication 接收系统事件即可。处理系统事件需要编写一个继承自 UIApplicationDelegate 接口的类,而 UIApplicationDelegate 接口提供生命周期函数来处理应用程序以及应用程序的系统事件。我们新建项目的时候,往往会自动生成一个继承自 UIApplicationDelegate 接口的类AppDelegate。

 

二、UIApplicationDelegate的生命周期

下面通过一个小demo理解UIApplicationDelegate常用生命周期中的方法:

#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的加载过程,如下图:

1354776680_2123

从图中可以看到,在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是如何被卸载的,如下图:

1354776741_7366

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

 

2、ViewController的生命周期

ViewController的生命周期中各方法执行流程如下图:

2954611-1695623d06b209cc

例如:

@interface ViewController ()

@end

@implementation ViewController

- (instancetype)init
{
    self = [super init];
    if (self) {
        NSLog(@"ViewController 初始化");
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        NSLog(@"ViewController 从归档初始化");
    }
    return self;
}

- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        self.view.backgroundColor = [UIColor whiteColor];
        NSLog(@"ViewController 从xib初始化");
    }
    return self;
}

- (void)loadView {
    [super loadView];
    NSLog(@"ViewController 开始加载视图");
}

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"ViewController 已经加载视图");
}

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];
    NSLog(@"ViewController 开始布局子视图");
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    NSLog(@"ViewController 完成布局子视图");
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    NSLog(@"ViewController 即将显示");
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    NSLog(@"ViewController 已经显示");
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    NSLog(@"ViewController 即将消失");
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    NSLog(@"ViewController 已经消失");
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    NSLog(@"ViewController 收到内存警告");
}


@end

打印结果:

2017-01-11 12:02:55.422 Test[11948:560350] ViewController 从归档初始化
2017-01-11 12:02:55.433 Test[11948:560350] ViewController 开始加载视图
2017-01-11 12:02:55.434 Test[11948:560350] ViewController 已经加载视图
2017-01-11 12:02:55.434 Test[11948:560350] ViewController 即将显示
2017-01-11 12:02:55.440 Test[11948:560350] ViewController 开始布局子视图
2017-01-11 12:02:55.440 Test[11948:560350] ViewController 完成布局子视图
2017-01-11 12:02:55.443 Test[11948:560350] ViewController 已经显示

 

原创文章,转载请注明: 转载自李峰峰博客

本文链接地址: iOS UIApplicationDelegate与UIViewController生命周期