博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ViewController生命周期(含viewDidLoad和loadView的特殊情况)
阅读量:4143 次
发布时间:2019-05-25

本文共 5870 字,大约阅读时间需要 19 分钟。

文章目录

前言

这里我用视图的显示顺序以及打印情况来表示函数调用顺序,即ViewController的生命周期

函数介绍

  • viewDidLoad:在视图加载后被调用,如果是在代码中创建的视图加载器,他将会在loadView方法后被调用,如果是从nib视图页面输出,他将会在视图设置好后后被调用。只会被调用一次,之后进入这个ViewController不调用此函数
  • viewLoad:每次访问controller的view(比如controller.view、self.view)且view为nil,loadView方法就会被调用。用于创建Controller的View
  • viewWillAppear: 视图将要显示
  • viewWillLayoutSubviews: 控制器的view将要布局子控件(在这个方法里,部署需要改变重新刷新view的代码,功能类似view的layoutSubViews()这个方法,需要注意的是,这个方法里一般都需要重置的view的frame,宽度和高度的获取,因此view的frame一般都写在这个方法里)
  • viewDidLayoutSubviews: 控制器的view布局子控件完成
  • viewDidAppear: 视图已经显示
  • viewWillDisappear: 视图将要消失
  • viewDidDisappear: 视图已经消失,在Controller被切换时调用,第二个视图出现后第一个视图消失

代码显示

我在调用每个函数都加一个颜色视图和打印一句话,在视图上添加一个按钮用于切换视图

  • viewDidLoad 上只添加了一个按钮
- (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];    }
  • viewDidAppear 是蓝色视图
- (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");}
  • viewDidDisappear: 是橙色视图
- (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");}
  • viewWillAppear: 是灰色视图
- (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");}
  • viewWillDisappear: 是红色视图
- (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");}
  • viewDidLayoutSubviews 是黄色视图
- (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");}
  • viewWillLayoutSubviews 是黑色视图
- (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 切换时的函数执行情况

  • 首先在viewDidLoad 里设置返回按钮
- (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];}
  • 4个简单函数
- (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/

你可能感兴趣的文章
java 设计模式-职责型模式
查看>>
构造型模式
查看>>
svn out of date 无法更新到最新版本
查看>>
java杂记
查看>>
RunTime.getRuntime().exec()
查看>>
Oracle 分组排序函数
查看>>
删除weblogic 域
查看>>
VMware Workstation 14中文破解版下载(附密钥)(笔记)
查看>>
日志框架学习
查看>>
日志框架学习2
查看>>
SVN-无法查看log,提示Want to go offline,时间显示1970问题,error主要是 url中 有一层的中文进行了2次encode
查看>>
NGINX
查看>>
Qt文件夹选择对话框
查看>>
1062 Talent and Virtue (25 分)
查看>>
1061 Dating (20 分)
查看>>
1060 Are They Equal (25 分)
查看>>
83. Remove Duplicates from Sorted List(easy)
查看>>
88. Merge Sorted Array(easy)
查看>>
leetcode刷题191 位1的个数 Number of 1 Bits(简单) Python Java
查看>>
leetcode刷题198 打家劫舍 House Robber(简单) Python Java
查看>>