本文共 5870 字,大约阅读时间需要 19 分钟。
这里我用视图的显示顺序以及打印情况来表示函数调用顺序,即ViewController的生命周期
我在调用每个函数都加一个颜色视图和打印一句话,在视图上添加一个按钮用于切换视图
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. NSLog(@"viewDidLoad"); UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [self.view addSubview:myButton]; [myButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [myButton setTitle:@"button" forState:UIControlStateNormal]; myButton.frame = CGRectMake([UIScreen mainScreen].bounds.size.width / 2, [UIScreen mainScreen].bounds.size.height / 4, [UIScreen mainScreen].bounds.size.width / 5, 50); [myButton addTarget:self action:@selector(press) forControlEvents:UIControlEventTouchUpInside]; }
- (void)viewDidAppear:(BOOL)animated { _blueView = [[UIView alloc] initWithFrame:CGRectMake(0, [UIScreen mainScreen].bounds.size.height / 3, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height / 1.5)]; [self.view addSubview:_blueView]; _blueView.backgroundColor = [UIColor blueColor]; NSLog(@"blueViewDidAppear");}
- (void)viewDidDisappear:(BOOL)animated { _orangeView = [[UIView alloc] initWithFrame:CGRectMake(0, [UIScreen mainScreen].bounds.size.height / 3, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height / 1.5)]; [self.view addSubview:_orangeView]; _orangeView.backgroundColor = [UIColor orangeColor]; NSLog(@"orangeViewDidDisappear");}
- (void)viewWillAppear:(BOOL)animated { _grayView = [[UIView alloc] initWithFrame:CGRectMake(0, [UIScreen mainScreen].bounds.size.height / 3, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height / 1.5)]; [self.view addSubview:_grayView]; _grayView.backgroundColor = [UIColor grayColor]; NSLog(@"grayViewWillAppear");}
- (void)viewWillDisappear:(BOOL)animated { _redView = [[UIView alloc] initWithFrame:CGRectMake(0, [UIScreen mainScreen].bounds.size.height / 3, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height / 1.5)]; [self.view addSubview:_redView]; _redView.backgroundColor = [UIColor redColor]; NSLog(@"redViewWillDisappear");}
- (void)viewDidLayoutSubviews { _yellowView = [[UIView alloc] initWithFrame:CGRectMake(0, [UIScreen mainScreen].bounds.size.height / 3, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height / 1.5)]; [self.view addSubview:_yellowView]; _yellowView.backgroundColor = [UIColor yellowColor]; NSLog(@"yellowViewDidLayoutSubviews");}
- (void)viewWillLayoutSubviews { _blackView = [[UIView alloc] initWithFrame:CGRectMake(0, [UIScreen mainScreen].bounds.size.height / 3, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height / 1.5)]; [self.view addSubview:_blackView]; _blackView.backgroundColor = [UIColor blackColor]; NSLog(@"blackViewWillLayoutSubviews");}
- (void)press { NSLog(@"----------------pressButton----------------"); sonViewController *son = [[sonViewController alloc] init]; [self presentViewController:son animated:NO completion:nil];}
执行出来的效果(不切换界面):
在第二个界面里设置一个返回按钮,在设置4个函数,用于显示视图2 和视图1 切换时的函数执行情况
- (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; // Do any additional setup after loading the view. UIButton *myButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [self.view addSubview:myButton]; [myButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [myButton setTitle:@"back" forState:UIControlStateNormal]; myButton.frame = CGRectMake([UIScreen mainScreen].bounds.size.width / 2, [UIScreen mainScreen].bounds.size.height / 2, [UIScreen mainScreen].bounds.size.width / 5, 50); [myButton addTarget:self action:@selector(press) forControlEvents:UIControlEventTouchUpInside];}
- (void)viewDidDisappear:(BOOL)animated { NSLog(@"view2DidDisappear");}- (void)viewWillDisappear:(BOOL)animated { NSLog(@"view2WillDisappear");}- (void)viewDidAppear:(BOOL)animated { NSLog(@"view2DidAppear");}- (void)viewWillAppear:(BOOL)animated { NSLog(@"view2WillAppear");}
- (void)press { NSLog(@"----------------pressBack----------------"); [self dismissViewControllerAnimated:NO completion:nil];}
点击后的情况:
说明在视图2 加载并完全显示出来以后,视图1 才完全消失点击返回按钮:
GitHub地址:
实验室分享时大家提出的疑问:如果函数viewDidLoad 和 loadView里都不写内容,代码如下:
- (void)viewDidLoad {// [super viewDidLoad]; NSLog(@"viewDidLoad");}- (void)loadView { NSLog(@"loadView");}- (void)viewWillAppear:(BOOL)animated { NSLog(@"viewWillAppear");}
经Xcode运行,结果如下:
(Xcode版本: 10.14.6) (之前版本) 为什么会有不一样的结果?为什么会走几遍就不走了?升级后为什么会走viewWillAppear?经过同学向学长的询问得知,Xcode有自己的防护机制。当程序运行时会先走loadView,然后运行到viewDidLoad时发现self.view为空,再返回loadView(loadView用于加载viewController的view),等再次执行到viewDidLoad时发现还是为空,viewDidLoad就启动防护机制不再让它返回请求。
这套防护机制是在哪里触发的?
我在viewDidLoad里加入调用self.view的语句,即- (void)viewDidLoad { self.view.backgroundColor = [UIColor whiteColor]; NSLog(@"viewDidLoad");}
执行,程序会陷入死循环最后报错。
得知,这套防护机制是存在于viewDidLoad里的,因为加入的语句不断强制调用loadView,使防护机制失效,故陷入死循环转载地址:http://xwkti.baihongyu.com/