ViewController 生命周期
- ViewController 生命周期
- 测试程序:ViewControllerLifeCircle
ViewController 生命周期
ViewController 是 iOS 开发中 MVC 框架中的 C,ViewColllecter 是 View(视图)的 Collecter(控制器)。ViewController 的职责主要包括管理内部各个 View 的加载显示和卸载,同时负责与其他 ViewController 的通信和协调。
iOS 中的 ViewController 分为两种:
-
显示视图的控制器。比如:UIViewController、UITableViewController等,同时还可以自定义继承自UIViewController的ViewController。
-
控制和管理视图,比如:
- UINavigationController:是 iOS 开发中的一个视图控制器容器,用于以栈(stack)的形式存储和管理其他视图控制器。通过它可以方便地实现应用程序的导航结构,比如在层级间进行导航、显示导航栏、处理返回操作等。这使得用户能够直观地浏览和切换不同的界面。
- UITabBarController:是 iOS 开发中的一个视图控制器容器,用于以标签页(tab)的形式存储和管理其他视图控制器。每个标签页代表一个视图控制器,用户可以通过点击不同的标签页来切换显示不同的视图控制器。UITabBarController 提供了一种方便的方式来组织和切换多个视图控制器,使用户可以快速访问不同的功能模块或视图。它常用于应用程序的主界面,如底部导航栏等。通过 UITabBarController,可以轻松实现多个视图控制器的切换和导航。
ViewController 生命周期会经历初始化、加载视图、销毁视图、生命结束等过程,流程执行如下图所示:
ViewController 生命周期中涉及的各种方法:
- init:初始化 ViewController 对象。
- loadView:在 UIViewController 对象的 view 被访问且为 nil 的时候调用。控制器 view 是通过懒加载的方式进行加载的,即用到的时候再加载。在 view 加载过程中首先会调用 loadView 方法,在这个方法中主要完成一些关键 view 的初始化工作,接下来就是加载 view,加载成功后,会接着调用 viewDidLoad 方法。在 loadView 之前,是没有 view 的,也就是说,在这之前,view 还没有被初始化。
- viewDidLoad:视图加载完成后调用。通常,对于各种初始化数据的载入,初始设定、修改约束、移除视图等很多操作都可以这个方法中实现。通常在此方法中添加一些控件和视图。注意这个方法在视图销毁之前只会调用一次。
- (void)viewWillAppear:(BOOL)animated {}:视图即将加入窗口时调用。在 viewDidLoad 将视图载入内存后,将会在屏幕上显示视图,这时会先调用这个方法。通常会在这个方法对即将显示的视图做进一步的设置。比如,设置设备不同方向时该如何显示、设置状态栏方向、设置视图显示样式等。
- (void)viewDidAppear:(BOOL)animated {}:视图已经加入到窗口时调用。这时可以对正在显示的视图做设置。
- (void)viewWillDisappear:(BOOL)animated {}:视图即将消失、被覆盖或是隐藏时调用。
- (void)viewDidDisappear:(BOOL)animated {}:视图已经消失、被覆盖或是隐藏时调用。
- viewDidUnload:系统内存不足时调用。内存吃紧时,在 iPhone OS 3.0 之前 didReceiveMemoryWarning 是释放无用内存的唯一方式,现在 viewDidUnload 方法是更好的方式。在该方法中将所有 IBOutlet 置为 nil,释放其他与 view 有关的对象、其他在运行时创建(但非系统必须)的对象、在 viewDidLoad 中被创建的对象、缓存数据等。
- dealloc:视图被销毁时调用。释放在 init 和 viewDidLoad 中创建的对象。
测试程序:ViewControllerLifeCircle
编写了一个 iOS 程序,实现了 2 个 ViewController,分别叫:AViewController、BViewController。重写了 2 个 ViewController 的各个生命周期的方法,让程序在对应页面的生命周期内打印当前执行的方法。在 AViewController 实现了一个按钮的点击事件,可以跳转到 BViewController,在 BViewController 也实现了一个按钮的点击事件,可以返回上个页面。
运行程序,在页面 A 点击按钮,跳转至 B,再点击 B 的按钮,返回 A。程序打印信息如下所示:
2024-06-27 18:50:37.563612+0800 ViewControllerLifeCircle[5412:1975949] AViewController: loadView
2024-06-27 18:50:37.564140+0800 ViewControllerLifeCircle[5412:1975949] AViewController: viewDidLoad
2024-06-27 18:50:37.564355+0800 ViewControllerLifeCircle[5412:1975949] AViewController: viewWillAppear
2024-06-27 18:50:37.624014+0800 ViewControllerLifeCircle[5412:1975949] AViewController: viewDidAppear
2024-06-27 18:50:44.922836+0800 ViewControllerLifeCircle[5412:1975949] A->B
2024-06-27 18:50:44.924060+0800 ViewControllerLifeCircle[5412:1975949] BViewController: loadView
2024-06-27 18:50:44.927415+0800 ViewControllerLifeCircle[5412:1975949] BViewController: viewDidLoad
2024-06-27 18:50:44.936887+0800 ViewControllerLifeCircle[5412:1975949] AViewController: viewWillDisappear
2024-06-27 18:50:44.937354+0800 ViewControllerLifeCircle[5412:1975949] BViewController: viewWillAppear
2024-06-27 18:50:44.947878+0800 ViewControllerLifeCircle[5412:1975949] BViewController: viewDidAppear
2024-06-27 18:50:44.948073+0800 ViewControllerLifeCircle[5412:1975949] AViewController: viewDidDisappear
2024-06-27 18:51:09.697424+0800 ViewControllerLifeCircle[5412:1975949] B->A
2024-06-27 18:51:09.704704+0800 ViewControllerLifeCircle[5412:1975949] BViewController: viewWillDisappear
2024-06-27 18:51:09.705139+0800 ViewControllerLifeCircle[5412:1975949] AViewController: viewWillAppear
2024-06-27 18:51:09.720304+0800 ViewControllerLifeCircle[5412:1975949] AViewController: viewDidAppear
2024-06-27 18:51:09.720551+0800 ViewControllerLifeCircle[5412:1975949] BViewController: viewDidDisappear
程序首先显示的是页面 A,所以走完了 AViewController 从加载到显示的生命周期。
从 A 跳转到 B,因为是第一次打开页面 B,所以要先执行 BViewController 的 loadView 方法,将界面 B 加载到内存后,后面的顺序是:AViewController: viewWillDisappear => BViewController: viewWillAppear => BViewController: viewDidAppear => AViewController: viewDidDisappear。
之后,从 B 返回 A,顺序也是按照:b.willDisappear => a.willAppear => a.didAppear => b.didDisappear。
程序源码位于 https://github.com/UestcXiye/Objective-C-Practice 的 ViewControllerLifeCircle 文件夹。