【iOS】ViewController的生命周期

【iOS】ViewController的生命周期

与ViewController生命周期有关的函数

  • Init

  • loadView()当需要展示view而view为nil时,ViewController会调用loadView方法。

  • viewDidLoad()类成员对象和变量的初始化都在这个方法里,在创建类后无论视图展现还是消失,这个方法只会在布局时调用一次

  • viewWillAppear():视图将要展现的时候调用

  • viewDidAppear():视图已经出现时调用

  • viewWillLayoutSubviews()用于处理视图布局的变化,通常在这里执行与布局相关的操作,在子视图重新布局之前调用

  • viewDidLayoutSubviews()用于处理视图布局的变化,在子视图重新布局之后调用

  • viewWillDisapper():视图即将消失时调用

  • viewDidDisapper():视图已经消失时调用

  • traitCollectionDidChange()视图控制器的特征集合发生变化时调用

  • didReceiveMemoryWarning()系统内存不足时调用

执行顺序

用一个简单的程序来展示一下这些函数的执行顺序,创建两个视图控制器并在两个视图控制器之间切换,在调用的函数中打印当前函数,以此来查看函数的调用情况。

AViewController:

objectivec 复制代码
#import "AViewController.h"
#import "BViewController.h"

@interface AViewController ()

@end

@implementation AViewController

- (void)viewDidLoad {
    
    UIColor *pinkColor = [UIColor colorWithRed:255/255.0 green:192/255.0 blue:203/255.0 alpha:1.0];
    UIColor *hotPinkColor = [UIColor colorWithRed:1.0 green:0.4117 blue:0.7059 alpha:1.0];
    
    [super viewDidLoad];
    self.view.backgroundColor = hotPinkColor;
    self.button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    self.button.frame = CGRectMake(137, 406, 120, 40);
    [self.view addSubview:self.button];
    [self.button setTitle:@"AGoToB" forState:UIControlStateNormal];
    [self.button setTitleColor:pinkColor forState:UIControlStateNormal];
    self.button.titleLabel.font = [UIFont systemFontOfSize:30];
    [self.button addTarget:self action:@selector(move) forControlEvents:UIControlEventTouchUpInside];
    NSLog(@"%s", __func__);
}

- (void)move {
    NSLog(@"A ------> B");
    BViewController* bViewController = [[BViewController alloc] init];
    bViewController.modalPresentationStyle = UIModalPresentationFullScreen;
    [self presentViewController:bViewController animated:YES completion:nil];
}

- (void)loadView {
    [super loadView];
    NSLog(@"%s", __func__);
}

- (void)viewWillAppear:(BOOL)animated {
    NSLog(@"%s", __func__);
}

- (void)viewDidAppear:(BOOL)animated {
    NSLog(@"%s", __func__);
}

- (void)viewWillLayoutSubviews {
    NSLog(@"%s", __func__);
}

- (void)viewDidLayoutSubviews {
    NSLog(@"%s", __func__);
}

- (void)viewWillDisappear:(BOOL)animated {
    NSLog(@"%s", __func__);
}

- (void)viewDidDisappear:(BOOL)animated {
    NSLog(@"%s", __func__);
}
@end

BViewController:

objectivec 复制代码
#import "BViewController.h"

@interface BViewController ()

@end

@implementation BViewController

- (void)viewDidLoad {
    
    UIColor *pinkColor = [UIColor colorWithRed:255/255.0 green:192/255.0 blue:203/255.0 alpha:1.0];
    UIColor *deepPinkColor = [UIColor colorWithRed:1.0 green:0.0784 blue:0.5765 alpha:1.0];
    
    [super viewDidLoad];
    self.view.backgroundColor = deepPinkColor;
    self.button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    self.button.frame = CGRectMake(117, 406, 160, 40);
    [self.button setTitle:@"BBackToA" forState:UIControlStateNormal];
    [self.view addSubview:self.button];
    [self.button setTitleColor:pinkColor forState:UIControlStateNormal];
    self.button.titleLabel.font = [UIFont systemFontOfSize:30];
    [self.button addTarget:self action:@selector(BBackToA) forControlEvents:UIControlEventTouchUpInside];
    NSLog(@"%s", __func__);
}

- (void)BBackToA {
    NSLog(@"B --------> A");
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)loadView {
    [super loadView];
    NSLog(@"%s", __func__);
}

- (void)viewWillAppear:(BOOL)animated {
    NSLog(@"%s", __func__);
}

- (void)viewDidAppear:(BOOL)animated {
    NSLog(@"%s", __func__);
}

- (void)viewWillLayoutSubviews {
    NSLog(@"%s", __func__);
}

- (void)viewDidLayoutSubviews {
    NSLog(@"%s", __func__);
}

- (void)viewWillDisappear:(BOOL)animated {
    NSLog(@"%s", __func__);
}

- (void)viewDidDisappear:(BOOL)animated {
    NSLog(@"%s", __func__);
}
@end

呈现效果:

程序输出:

根据程序的输出我们总结出:

  • 对于单个视图控制器,函数调用的顺序是:loadView -> viewDidLoad -> viewWillAppear -> viewWillLayoutSubviews -> viewDidLayoutSubviews -> viewDidAppear

  • 对于两个视图控制器互相切换,被切换的视图控制器会先调用viewWillDisapper,直到切换出来的视图控制器调用viewDidAppear后,被切换的视图控制器才会调用viewDidDisapper。以上图为例:AviewController先调用viewWillDisapper,然后BviewController调用一系列函数,直到BviewController调用viewDidAppear后,AviewController才调用viewDidDisappear

另外,这里AviewController只调用过一次loadView,BviewController多次反复调用loadView,由此可知,在BviewController执行完dismiss后,内存就被释放掉了,而AviewController作为根视图控制器是一直没有被释放的

注意

这里loadview的函数中写上[super loadview],这是因为当view为nil时,就会调用loadview方法。如果找不到view的话,程序就会一直调用loadview方法来寻找view。

特殊视图控制器中生命周期

  • UINavgationController是一种用来控制和管理UIViewController的类,通过栈的方式,视图控制器之间有一层层的层级关系,出栈后视图会被卸载。
  • UITabBarController也是用来控制和管理的UIViewController的类,并且TabBarController是以数组的形式将分栏信息添加到手机屏幕上,视图之间的关系是平级的,没有层级之分,切换之后视图不会被移除
相关推荐
Red Red1 分钟前
GEO数据库提取疾病样本和正常样本|GEO数据库区分疾病和正常样本|直接用|生物信息|生信
开发语言·数据库·笔记·学习·r语言·c#·生物信息
视觉小鸟12 分钟前
【java面试每日五题之基础篇一】(仅个人理解)
java·笔记·面试
handsome2135 小时前
WSL中使用GPU加速AMBER MD--测试
笔记·学习
WZF-Sang6 小时前
Linux权限理解【Shell的理解】【linux权限的概念、管理、切换】【粘滞位理解】
linux·运维·服务器·开发语言·学习
狂飙的张兴发7 小时前
认知小文2《成功之路:习惯、学习与实践》
学习·考研·职场和发展·跳槽·学习方法·改行学it·高考
爱编程的小新☆7 小时前
C语言内存函数
c语言·开发语言·学习
夜清寒风8 小时前
opencv学习:图像掩码处理和直方图分析及完整代码
人工智能·opencv·学习·算法·机器学习·计算机视觉
吃着火锅x唱着歌8 小时前
Go语言设计与实现 学习笔记 第七章 内存管理(1)
笔记·学习·golang
~在杰难逃~9 小时前
关于订单信息的Excel数据分析报告
笔记·数据分析·excel·数据分析报告
我命由我123459 小时前
2.使用 VSCode 过程中的英语积累 - Edit 菜单(每一次重点积累 5 个单词)
前端·javascript·ide·vscode·学习·编辑器·学习方法