UIViewController的生命周期

发布于:2022-12-16 ⋅ 阅读:(648) ⋅ 点赞:(0)


前言

UIViewController详情可见MVC模式


UIViewController

定义

UIViewController是MVC模式中连接M和V的桥梁
继承关系:UIViewController : UIResponder : NSObject
UIViewController是用来管理View的。它具有但是不限于在View中出现或消失时调用的方法。UIViewController没有继承与UIView,它不属于视图,也不显示任何内容,没有frame的概念。但是UIViewController里有view的属性,我们可以用self.view来显示内容

作用

  1. 更新视图内容的显示
  2. 影响用户与视图的交互
  3. 调整视图大小
  4. 管理页面布局
  5. 与其他对象协调

生命周期

这个是Apple官方给出的图
在这里插入图片描述

方法介绍

方法 作用
init方法 初始化UIViewController
loadView 当view需要被展示而它却是nil,viewController会调用该方法
viewDidLoad 执行完loadView后执行
viewWillAppear 对象视图即将加入窗口时调用
viewWillDidAppear 已经加入窗口时调用
viewWillDisAppear 视图即将消失,被覆盖或者隐藏时调用
viewDidDisAppear 视图已经消失,被覆盖或是隐藏时调用
viewDidUnLoad 一般情况下发生在内存警告
dealloc 释放内存,销毁视图

loadView

loadView中只初始化view;一般用于创建比较关键的view,例如UItableViewController的 tableView,UINavigationController的navgationBar,不可调用view的getter (在调用super 的loadView前),最好也不要初始化一些非关键的view。如果你是从nib文件中创建的viewController在这里一定要首先调用 super的loadView方法,但建议不要重载这个方法。

viewDidLoad

此时view已经有了,最适合初始化控件。需注意ViewDidLoad可能会调用多次。(在viewController多次载入view的时候)

viewWillAppear

一般在view被添加到superview之前,切换动画之前调用。可以进行一些显示前的处理,

viewDidUnLoad

此时的view已经是nil了,可能会发生内存警告。所以我们应该在这里释放那些不在显示的view。

在这里我使用了一个页面上添加按钮跳转至下一页面在点击按钮跳转回的方法来举例

//  ViewController.m
//  text.9.15
//
//

#import "ViewController.h"
#import "SecondViewController.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"loadView 1");
    self.view.backgroundColor = [UIColor orangeColor];
    UIButton* button = [[UIButton alloc] init];
    button.frame = CGRectMake(100, 100, 100, 50);
    [button setTitle:@"跳转" forState:UIControlStateNormal];
    button.backgroundColor = [UIColor blueColor];
    [button addTarget:self action:@selector(press) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
    // Do any additional setup after loading the view.
}
- (void)press{
    SecondViewController* second = [[SecondViewController alloc] init];
    [self presentViewController:second animated:YES completion:nil];
}
- (void)viewWillAppear:(BOOL)animated{
    NSLog(@"viewWillAppear 1");
}
- (void)viewDidAppear:(BOOL)animated{
    
    NSLog(@"viewDidAppear 1");
}
- (void)viewWillDisappear:(BOOL)animated{
    
    NSLog(@"viewWillDisappear 1");
}
- (void)viewDidDisappear:(BOOL)animated{
    
    NSLog(@"viewDidDisappear 1");
}
@end


//  SecondViewController.m
//  text.9.15
//
//

#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"loadView 2");
    self.view.backgroundColor = [UIColor greenColor];
    UIButton* button = [[UIButton alloc] init];
    button.frame = CGRectMake(100, 100, 100, 50);
    button.backgroundColor = [UIColor blueColor];
    [button setTitle:@"返回" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(press) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
    // Do any additional setup after loading the view.
}
- (void)press{
    [self dismissViewControllerAnimated:YES completion:nil];
}
- (void)viewWillAppear:(BOOL)animated{
    NSLog(@"viewWillAppear 2");
}
- (void)viewDidAppear:(BOOL)animated{
    
    NSLog(@"viewDidAppear 2");
}
- (void)viewWillDisappear:(BOOL)animated{
    
    NSLog(@"viewWillDisappear 2");
}
- (void)viewDidDisappear:(BOOL)animated{
    
    NSLog(@"viewDidDisappear 2");
}
/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end


这里是代码运行结果
在这里插入图片描述
通过观察代码运行结果可以发现没有第一界面的消失过程
我们在第一界面的函数里面写上这行代码,这行代码的意思是使SecondView弹出并占据整个屏幕


    second.modalPresentationStyle = UIModalPresentationFullScreen;

这里是代码运行结果
在这里插入图片描述
这样第一界面的消失过程也出现了


[super viewDidLoad]

父类中的viewDidLoad会做一些初始化的工作,比如A是基类,B从A继承,B在viewDidLoad方法中创建和初始化了一些成员,C继承B,如果C在调用viewDidLoad的时候没有调用[super viewDidLoad]方法,那么就会有一些成员没有被初始化,可能就会产生问题。

loadView这个方法是系统默认创建的 因为重写了这个方法导致必须要继承其父类的方法,如果不写继承的loadView,无法继承父系的loadview的创建方法,那么就永远无法创建,那么就会陷入循环。


网站公告

今日签到

点亮在社区的每一天
去签到