【iOS】ViewController的生命周期

news2024/11/17 7:39:25

文章目录

  • 前言
  • 一、UIViewController生命周期有关函数
  • 二、执行顺序
  • 注意点
    • loadview:


前言

在iOS开发中UIViewController扮演者非常重要的角色,它是视图view和数据model的桥梁,通过UIViewController的管理有条不紊的将数据展示在视图上。作为UIKit中最基本的一个类,一般复杂的项目都离不开UIViewController作为基类。所以了解UIViewController的整个生命周期是有必要的。


一、UIViewController生命周期有关函数

以下是UIViewController生命周期方法的调用函数:

  • init(coder:) 或 init(nibName:bundle:)(根据视图的加载方式而定,可能不会同时调用)

init方法和initCoder方法相似,知识被调用的环境不一样。如果用代码初始化,会调用init方法,从nib文件或者归档(xib、storyboard)进行初始化会调用initCoder。initCoder是NSCoding协议中的方法,NSCoding是负责编码解码,归档处理的协议。

  • loadView():当View需要被展示而它却是nil时,ViewController会调用该方法。
    如果代码维护View的话需要重写此方法,使用xib维护View的话不用重写。
  • viewDidLoad():我们最常用的方法,类成员对象和变量的初始化我们都会放在这个方法中。在创建类后无论视图展现还是消失,这个方法也只会在布局是调用一次。
  • viewWillAppear():是在视图将要展现出来的时候调用。
  • viewDidAppear():方法是视图已经出现。
  • viewWillLayoutSubviews(), viewDidLayoutSubviews():这些方法用于处理视图布局的变化,通常在这里执行与布局相关的操作。viewWillLayoutSubviews()在子视图重新布局之前被调用,而viewDidLayoutSubviews()在子视图重新布局之后被调用。
  • viewWillDisappear():方法是视图即将消失。 -viewDidDisappear():视图已经消失。
  • traitCollectionDidChange()(如果视图控制器的特征集合发生变化)
  • didReceiveMemoryWarning()(如果系统内存不足)

二、执行顺序

我们用一个程序示例来看我们的执行顺序:我们创建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
  • 当两个视图控制器来回切换,我们的第一个视图控制器不会直接调用disAppear函数,而是当第二个视图控制器didAppaer之后才会调用disAppear函数,反之也是如此

注意点

loadview:

每次访问UIViewController的view(比如vc.view、self.view)而且view为nil,loadView方法就会被调用。这也是为什么我们重写loadview方法时必须要加上[super loadView];,因为调用这个方法可以自动生成我们的view。如果我们找不到view,我们的程序就会一直调用loadview方法来寻找我们的view。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1018686.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

XML 和 JSON 学习笔记(基础)

XML Why XML 的出现背景:在实际开发中,不同语言(如Java、JavaScript等)的应用程序之间数据传递的格式不同,导致它们进行数据交换时很困难,XML就应运而生了!(XML 是一种通用的数据交…

视频分析【video analytics】的项目的关键因素 -- 如何选择合适的摄像头,存储设备,以及AI推理硬件?

文字大纲 参考指标摄像机存储设备AI 推理硬件参考文献与学习路径参考指标 摄像机 通常的做法是将视频视为一系列图像(帧),并使用仅在图像上训练的深度神经网络模型来执行视频上的相似分析任务。在这篇论文中,我们表明,这种在图像上运行良好的深度学习模型在视频上也会运行…

QT:使用普通按钮、网格布局管理器、标签、行编辑器、水平布局管理器、垂直布局管理器做一个小项目

widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPushButton> //普通按钮 #include <QGridLayout> //网格布局管理器 #include <QLabel> //标签 #include <QLineEdit> //行编辑器 #include <QHBoxLayo…

core文件的生成与使用

目录 core 设置例子 1例子 2core 名称及目录修改参考 在使用嵌入式系统时&#xff0c;出错后&#xff0c;不好使用 gdb 调试&#xff0c;这时&#xff0c;可让系统生成一个 core 文件&#xff0c;用于查看出错原因 core 设置 要生成 core 文件&#xff0c;需要先设置 core 文…

链表的基本操作(acm模式,中等)

此题自己亲自动手实现难度确实不容易&#xff0c;为了更好的掌握 链表这一结构&#xff0c;还是得自己敲&#xff0c;自己debug,还得多次看&#xff0c;才能脑子清楚&#xff0c;手也熟。 // 本题的删除索引是从1开始&#xff0c;函数实现是从0开始&#xff0c;先说明这一点&a…

基于SSM的高校教师科研信息展示网站的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

[自用]手推DDPM公式

正向最终呈N(0,1) 逆向可解 用神经网络预测逆向的噪声ε&#xff0c;与正向的噪声做MSE

列属性与数据完整性

1.2 数据类型——值类型 1.2.1 整型 类型字节范围tinyint1-128~127smallint2-32768~32767mediumint3-8388608~8388607int4-231~231-1bigint8-263~263-1 1、无符号整数&#xff08;unsigned&#xff09;&#xff1a;无符号数没有负数&#xff0c;正数部分是有符号的两倍。 例…

解决Qt VS Tools扩展加载预编译Qt库 提示版本不匹配

提示 qmake error:no value for QT_INSTALL_PREFIX/src 原因&#xff1a; qt路径编译时&#xff0c;是硬编码到qmake里的&#xff0c;所以如果挪动了qt的目录&#xff0c;或者是下载其他人预编译的qt库&#xff0c;就会有该提示。 解决方案&#xff1a; qmake同级别路径新建q…

docker 和k8s 入门

docker 和k8s 入门 本文是云原生的学习记录&#xff0c;可以参考以下文档 k8s https://www.yuque.com/leifengyang/oncloud 相关视频教程可参考如下 https://www.bilibili.com/video/BV13Q4y1C7hS?p2&vd_source0882f549dac54045384d4a921596e234 相对于公有云&#x…

6.3、Flink数据写入到MySQL

目录 1、添加POM依赖 2、这一个完整的案例 3、何时批量写入MySQL呢&#xff1f; 4、容错性的保证(精确一次&至少一次) 4.1、 至少一次 4.2、精确一次 1、添加POM依赖 Apache Flink 集成了通用的 JDBC 连接器&#xff0c;使用时需要根据生产环境的版本引入相应的依赖…

哈夫曼编码原理及实现

文章目录 一.哈夫曼编码原理哈夫曼二叉树构建 二.具体代码实现 一.哈夫曼编码原理 哈夫曼编码&#xff08;Huffman Coding&#xff09;是一种用于数据压缩的编码方法&#xff0c;它通过给出不同的数据符号分配不同长度的编码&#xff0c;使得出现频率高的符号具有较短的编码&a…

MySql中分割字符串

MySql中分割字符串 在MySql中分割字符串可以用到SUBSTRING_INDEX&#xff08;str, delim, count&#xff09; 参数解说       解释 str         需要拆分的字符串 delim         分隔符&#xff0c;通过某字符进行拆分 count          当 count 为正数&…

Web 第一步:HTTP 协议(基础)

这里是JavaWeb的开头部分&#xff01;那么先解释一下吧&#xff1a; Web&#xff1a;全球广域网&#xff0c;也称为万维网&#xff08;www&#xff09;&#xff0c;能够通过浏览器访问的网站。 JavaWeb&#xff1a;是用Java技术来解决相关 Web 互联网领域的技术栈。 &#xf…

Java8中判断一个对象不为空存在一个类对象是哪个

Java8中判断一个对象不为空存在一个类对象是哪个&#xff1f; 在Java 8中&#xff0c;你可以使用java.util.Optional类来处理可能为空的对象。Optional类可以帮助你优雅地处理空值情况&#xff0c;而不需要显式地进行空值检查。 这是一个简单的Optional示例&#xff1a; imp…

蓝桥杯 题库 简单 每日十题 day3

01 约数个数 题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 1200000 有多少个约数&#xff08;只计算正约数&#xff09;。 解题思路 枚举&#xff0c;从1开始一直到1200000本身都作为1200000的除数&#xff0c;…

操作系统03-IO设备管理

中断源指的就是中断请求&#xff0c;所谓中断字是指中断请求的编号。 内存不足时候&#xff0c;OS可以采取“内存紧缩”进行改善。 进程控制块PCB组织管理一般采用线性方式。 7个状态模型增加就绪挂起和阻塞挂起的状态&#xff1a;1提高效率 2 提供足够的内存 3有利于调试 生…

【电子学会】2023年05月图形化三级 -- 数星星

数星星 1. 准备工作 &#xff08;1&#xff09;删除默认角色小猫&#xff0c;添加角色Pico和Star&#xff1b; &#xff08;2&#xff09;添加背景&#xff1a;Stars。 2. 功能实现 &#xff08;1&#xff09;Pico位置在舞台左下角&#xff1b; &#xff08;2&#xff09;…

springboot和vue:三、web入门(spring-boot-starter- web+控制器+路由映射+参数传递)

spring-boot-starter- web Spring Boot将传统Web开发的mvc、json、tomcat等框架整合&#xff0c;提供了spring-boot-starter-web组件&#xff0c;简化了Web应用配置。创建SpringBoot项目勾选Spring Web选项后&#xff0c;会自动将spring-boot-starter- web组件加入到项目中。w…