• 【iOS】ViewController的生命周期



    前言

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    #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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    在这里插入图片描述
    输出结果:

    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:]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    由此可以得出我们ViewController的生命周期执行顺序:

    • 当仅仅弹出单个视图控制器
    loadView->didloadView->willAppear->willLayoutsubviews->didLayoutSubviews->didAppear
    
    • 1
    • 当两个视图控制器来回切换,我们的第一个视图控制器不会直接调用disAppear函数,而是当第二个视图控制器didAppaer之后才会调用disAppear函数,反之也是如此

    注意点

    loadview:

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

  • 相关阅读:
    计算机毕业设计SSM电影网站系统【附源码数据库】
    R基本语法
    Debian12安装 Docker
    Revit SDK 介绍:RayTraceBounce 光线反弹
    记一次某制造业ERP系统 CPU打爆事故分析
    MySQL(6)LOCK和MVCC
    C# 实现 Linux 视频会议(源码,支持信创环境,银河麒麟,统信UOS)
    C/C++内存管理
    马斯克发布人形机器人进展,它是否“中看不中用”?
    MCE丨重组蛋白常见的融合标签
  • 原文地址:https://blog.csdn.net/weixin_72437555/article/details/132889032