在iOS开发中UIViewController扮演者非常重要的角色,它是视图view和数据model的桥梁,通过UIViewController的管理有条不紊的将数据展示在视图上。作为UIKit中最基本的一个类,一般复杂的项目都离不开UIViewController作为基类。所以了解UIViewController的整个生命周期是有必要的。
以下是UIViewController生命周期方法的调用函数:
init方法和initCoder方法相似,知识被调用的环境不一样。如果用代码初始化,会调用init方法,从nib文件或者归档(xib、storyboard)进行初始化会调用initCoder。initCoder是NSCoding协议中的方法,NSCoding是负责编码解码,归档处理的协议。
我们用一个程序示例来看我们的执行顺序:我们创建AB两个viewcontroller,然后设置一个按钮让他们之间可以进行切换
#import "AViewController.h"
#import "BViewController.h"
@interface AViewController ()
@end
@implementation AViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor redColor];
_btn1 = [UIButton buttonWithType:UIButtonTypeSystem];
[_btn1 setTitle:@"next_push" forState:UIControlStateNormal];
_btn1.frame = CGRectMake(self.view.frame.size.width / 2 - 50, self.view.frame.size.height / 2 - 50, 200, 100);
[self.view addSubview:_btn1];
[_btn1 addTarget:self action:@selector(next_present) forControlEvents:UIControlEventTouchUpInside];
NSLog(@"%s", __func__);
}
- (void)next_present {
BViewController *B = [[BViewController alloc] init];
NSLog(@"---------A->B---------");
B.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:B animated:YES completion:nil];
}
- (void)loadView {
[super loadView];
NSLog(@"%s", __func__);
}
- (void)viewWillAppear:(BOOL)animated {
NSLog(@"%s", __func__);
}
- (void)viewWillLayoutSubviews {
NSLog(@"%s", __func__);
}
- (void)viewDidLayoutSubviews {
NSLog(@"%s", __func__);
}
- (void)viewDidAppear:(BOOL)animated {
NSLog(@"%s", __func__);
}
- (void)viewWillDisappear:(BOOL)animated {
NSLog(@"%s", __func__);
}
- (void)viewDidDisappear:(BOOL)animated {
NSLog(@"%s", __func__);
}
@end
#import "BViewController.h"
@interface BViewController ()
@end
@implementation BViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor greenColor];
_btn1 = [UIButton buttonWithType:UIButtonTypeSystem];
[_btn1 setTitle:@"present" forState:UIControlStateNormal];
_btn1.frame = CGRectMake(self.view.frame.size.width / 2 - 50, self.view.frame.size.height / 2 - 50, 200, 100);
[self.view addSubview:_btn1];
[_btn1 addTarget:self action:@selector(next_present) forControlEvents:UIControlEventTouchUpInside];
NSLog(@"%s", __func__);
}
- (void)next_present {
NSLog(@"---------B->A---------");
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)loadView {
[super loadView];
NSLog(@"%s", __func__);
}
- (void)viewWillAppear:(BOOL)animated {
NSLog(@"%s", __func__);
}
- (void)viewWillLayoutSubviews {
NSLog(@"%s", __func__);
}
- (void)viewDidLayoutSubviews {
NSLog(@"%s", __func__);
}
- (void)viewDidAppear:(BOOL)animated {
NSLog(@"%s", __func__);
}
- (void)viewWillDisappear:(BOOL)animated {
NSLog(@"%s", __func__);
}
- (void)viewDidDisappear:(BOOL)animated {
NSLog(@"%s", __func__);
}
@end

输出结果:
2023-09-15 09:24:00.429478+0800 viewcontroller[13601:419399] -[AViewController loadView]
2023-09-15 09:24:00.432183+0800 viewcontroller[13601:419399] -[AViewController viewDidLoad]
2023-09-15 09:24:00.436078+0800 viewcontroller[13601:419399] -[AViewController viewWillAppear:]
2023-09-15 09:24:00.438626+0800 viewcontroller[13601:419399] -[AViewController viewWillLayoutSubviews]
2023-09-15 09:24:00.438685+0800 viewcontroller[13601:419399] -[AViewController viewDidLayoutSubviews]
2023-09-15 09:24:00.459615+0800 viewcontroller[13601:419399] -[AViewController viewDidAppear:]
2023-09-15 09:24:01.630610+0800 viewcontroller[13601:419399] ---------A->B---------
2023-09-15 09:24:01.631055+0800 viewcontroller[13601:419399] -[BViewController loadView]
2023-09-15 09:24:01.631497+0800 viewcontroller[13601:419399] -[BViewController viewDidLoad]
2023-09-15 09:24:01.635034+0800 viewcontroller[13601:419399] -[AViewController viewWillDisappear:]
2023-09-15 09:24:01.635241+0800 viewcontroller[13601:419399] -[BViewController viewWillAppear:]
2023-09-15 09:24:01.637124+0800 viewcontroller[13601:419399] -[BViewController viewWillLayoutSubviews]
2023-09-15 09:24:01.637377+0800 viewcontroller[13601:419399] -[BViewController viewDidLayoutSubviews]
2023-09-15 09:24:02.142068+0800 viewcontroller[13601:419399] -[BViewController viewDidAppear:]
2023-09-15 09:24:02.142392+0800 viewcontroller[13601:419399] -[AViewController viewDidDisappear:]
2023-09-15 09:24:02.397591+0800 viewcontroller[13601:419399] ---------B->A---------
2023-09-15 09:24:02.400464+0800 viewcontroller[13601:419399] -[BViewController viewWillDisappear:]
2023-09-15 09:24:02.400764+0800 viewcontroller[13601:419399] -[AViewController viewWillAppear:]
2023-09-15 09:24:02.906699+0800 viewcontroller[13601:419399] -[AViewController viewDidAppear:]
2023-09-15 09:24:02.906936+0800 viewcontroller[13601:419399] -[BViewController viewDidDisappear:]
2023-09-15 09:24:03.331584+0800 viewcontroller[13601:419399] ---------A->B---------
2023-09-15 09:24:03.332027+0800 viewcontroller[13601:419399] -[BViewController loadView]
2023-09-15 09:24:03.332457+0800 viewcontroller[13601:419399] -[BViewController viewDidLoad]
2023-09-15 09:24:03.335091+0800 viewcontroller[13601:419399] -[AViewController viewWillDisappear:]
2023-09-15 09:24:03.335375+0800 viewcontroller[13601:419399] -[BViewController viewWillAppear:]
2023-09-15 09:24:03.336893+0800 viewcontroller[13601:419399] -[BViewController viewWillLayoutSubviews]
2023-09-15 09:24:03.337049+0800 viewcontroller[13601:419399] -[BViewController viewDidLayoutSubviews]
2023-09-15 09:24:03.841095+0800 viewcontroller[13601:419399] -[BViewController viewDidAppear:]
2023-09-15 09:24:03.841359+0800 viewcontroller[13601:419399] -[AViewController viewDidDisappear:]
2023-09-15 09:24:04.031338+0800 viewcontroller[13601:419399] ---------B->A---------
2023-09-15 09:24:04.033750+0800 viewcontroller[13601:419399] -[BViewController viewWillDisappear:]
2023-09-15 09:24:04.033976+0800 viewcontroller[13601:419399] -[AViewController viewWillAppear:]
2023-09-15 09:24:04.537921+0800 viewcontroller[13601:419399] -[AViewController viewDidAppear:]
2023-09-15 09:24:04.538108+0800 viewcontroller[13601:419399] -[BViewController viewDidDisappear:]
由此可以得出我们ViewController的生命周期执行顺序:
loadView->didloadView->willAppear->willLayoutsubviews->didLayoutSubviews->didAppear
每次访问UIViewController的view(比如vc.view、self.view)而且view为nil,loadView方法就会被调用。这也是为什么我们重写loadview方法时必须要加上[super loadView];,因为调用这个方法可以自动生成我们的view。如果我们找不到view,我们的程序就会一直调用loadview方法来寻找我们的view。