【iOS】UIViewController生命周期

UIViewController的生命周期

前言

在iOS开发中,UIViewController是一个很重要的概念。在学习MVC中,我们知道它是view和model的桥梁。UIViewController作为UIKit中最基本的一个类,我们很有必要学习了解一下UIViewController的生命周期。

UIViewController函数

首先我们展示一下UIViewController整个生命周期的执行流程图:

为了更直观的感受整个UIViewController生命周期的执行流程,这里通过一个demo来NSLog一下函数:

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

@interface AViewController ()

@property(nonatomic, strong) UIButton *btn;

@end

@implementation AViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    self.btn = [UIButton buttonWithType:UIButtonTypeSystem];
    [self.btn setTitle:@"去B" forState:UIControlStateNormal];
    [self.btn addTarget:self action:@selector(pressBtn) forControlEvents:UIControlEventTouchUpInside];
    self.btn.frame = CGRectMake(100, 300, 50, 50);
    [self.view addSubview:self.btn];
}

-(void)pressBtn {
    BViewController *bVC = [[BViewController alloc] init];
    NSLog(@"A到B");
    bVC.modalPresentationStyle = UIModalPresentationFullScreen;
    [self presentViewController:bVC 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
objc 复制代码
#import "BViewController.h"

@interface BViewController ()

@property(nonatomic, strong) UIButton *btn;

@end

@implementation BViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor greenColor];
    self.btn = [UIButton buttonWithType:UIButtonTypeSystem];
    [self.btn setTitle:@"去A" forState:UIControlStateNormal];
    self.btn.frame = CGRectMake(100, 300, 50, 50);
    [self.btn addTarget:self action:@selector(pressBtn) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:self.btn];
}

-(void)pressBtn {
    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

这样我们就能从输出直观的看出整个UIViewController的执行顺序:

具体介绍一下每个方法:

初始化

init(coder:) 或 init(nibName:bundle:) :初始化。

比较 init 方法和 initWithCoder: 方法:

  • init:用于代码中直接初始化对象,手动通过alloc init创建对象。
  • initWithCoder:
    • NSCoding(负责归档解档的协议)协议中需要实现的方法。
    • xib、storyboard中的UI元素初始化加载时调用。

加载视图

  • loadView():当view需要被展示而它却是nil时,ViewController会调用该方法。
    • 如果是代码创建的控制器,系统会创建一个空白的UIView并赋给self.view,因此需要重写。
    • 如果控制器是从Storyboard/XIB加载的,系统会自动将nib文件里的根视图赋给self.view,因此一般不需要重写。
  • viewDidLoad():最常用的方法,类成员对象和变量的初始化写在该方法中。但是在类创建后无论视图展现还是消失,这个方法只能调用一次。

注意⚠️:着重区分一下loadView()和viewDidLoad():

  • 触发时间:
    • loadView():view第一次被访问时
    • viewDidLoad():在loadView()执行完后触发
  • 主要职责:
    • loadView():创建并设置self.view
    • viewDidLoad():做视图额外的初始化

形象的说,loadView()好比建房子,viewDidLoad()好比装修房子。

  • viewWillAppear():视图将要展现出来时调用。
  • viewDidAppear():视图已经展现出来后调用。
  • 用于处理视图布局的变化,通常在这里执行与布局相关的操作:
    • viewWillLayoutSubviews():子视图重新布局前被调用。
    • viewDidLayoutSubviews():子视图重新布局后被调用。
  • viewWillDisappear():视图即将消失时调用。
  • viewDidDisappear():视图已经消失时调用。
  • traitCollectionDidChange():当视图控制器的环境特征发生变化时调用,比如深色模式切换、横竖屏切换、多任务分屏导致的size class变化等。用于响应界面环境变化,更新UI样式。

内存警告

didReceiveMemoryWarning():当系统检测到内存不足时调用,用于释放不必要的内存资源。

视图销毁

dealloc():当对象的引用计数为0时自动调用,销毁视图,释放资源。

总结

以上就是我学习的UIViewController生命周期小结。

相关推荐
国科安芯11 小时前
核电站仪控与监测系统中抗辐射 MCU 芯片应用研究
单片机·嵌入式硬件·macos·无人机·cocos2d·核电站
@大迁世界11 小时前
14个你现在必须关闭的 iOS 26 设置,不然手机很快被它榨干
macos·ios·智能手机·objective-c·cocoa
健忘的萝卜11 小时前
Clawdbot 爆红硅谷,也把 AI Agent 和 Mac mini 推上风口
人工智能·macos·agent·数字员工·clawbot
YJlio19 小时前
10.2.8 以其他账户运行服务(Running services in alternate accounts):为什么“把服务切到某个用户账号下运行”,本质上是在改变服务的整个安全上下文?
python·安全·ios·机器人·django·iphone·7-zip
HashFlag21 小时前
Mac新机基础配置
macos
承渊政道1 天前
【动态规划算法】(子序列问题解题框架与典型案例)
数据结构·c++·学习·算法·leetcode·macos·动态规划
pop_xiaoli1 天前
【iOS】KVC与KVO
笔记·macos·ios·objective-c·cocoa
SkyXZ~1 天前
Mac上使用VScode优雅开发STM32
vscode·stm32·macos
90后的晨仔1 天前
《swiftUI进阶 第10章:现代状态管理(iOS 17+)》
ios
brucelee1861 天前
Claude Code 安装教程(Windows / Linux / macOS)
linux·windows·macos