iOS:從頭捋一遍VC的生命週期

1、介紹app

UIViewController是iOS開發中的核心控件,沒有它那基本上任何功能都沒法實現,雖然系統已經作了全部控件的生命維護,可是,瞭解它的生命週期是如何管理仍是很是有必要的。網上有不少教程,別人寫的始終是別人的,本身動手實踐一下,理解才能更深入,本文就來捋一遍VC的生命週期。ide

 

2、思路函數

經過三個VC,第1個VC是storyBoard建立的,第2個VC是純code建立的,第3個是xib建立的。分別稱爲BoardInitViewController、CodeInitViewController、XibInitViewController,這三個控制器採用導航模式進行交互,如今在VC中把全部跟初始化相關的方法都實現一下並作打印,以下:佈局

BoardInitViewController:spa

//
//  BoardInitViewController.m
//  聲明週期
//
//  Created by 夏遠全 on 2019/11/3.
//  Copyright © 2019 Beijing Huayue Education Technology Co., Ltd. All rights reserved.
//

#import "BoardInitViewController.h"
#import "CodeInitViewController.h"

@interface BoardInitViewController ()

@end

@implementation BoardInitViewController

+(void)load {
    [super load];
    NSLog(@"boardVc---------%s",__func__);
}

+(void)initialize {
    [super initialize];
    NSLog(@"boardVc---------%s",__func__);
}

+(instancetype)alloc {
    NSLog(@"boardVc---------%s",__func__);
    return [super alloc];
}

- (nullable instancetype)initWithCoder:(NSCoder *)coder {
    NSLog(@"boardVc---------%s",__func__);
    return [super initWithCoder:coder];
}

- (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil {
    NSLog(@"boardVc---------%s",__func__);
    return [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
}

-(instancetype)init {
    NSLog(@"boardVc---------%s",__func__);
    return [super init];
}

- (void)loadView {
    [super loadView];
    NSLog(@"boardVc---------%s",__func__);
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor greenColor];
    self.title = @"boardVc";
    NSLog(@"boardVc---------%s",__func__);
}

- (void)viewWillAppear:(BOOL)animated  {
    [super viewWillAppear:animated];
    NSLog(@"boardVc---------%s",__func__);
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    NSLog(@"boardVc---------%s",__func__);
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    NSLog(@"boardVc---------%s",__func__);
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    NSLog(@"boardVc---------%s",__func__);
}

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];
    NSLog(@"boardVc---------%s",__func__);
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    NSLog(@"boardVc---------%s",__func__);
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    NSLog(@"boardVc---------%s",__func__);
}

-(void)dealloc {
    NSLog(@"boardVc---------%s",__func__);
}



-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    CodeInitViewController *codeVc = [[CodeInitViewController alloc] init];
    [self.navigationController pushViewController:codeVc animated:YES];
}

@end
View Code

CodeInitViewController:code

//
//  CodeInitViewController.m
//  聲明週期
//
//  Created by 夏遠全 on 2019/11/3.
//  Copyright © 2019 Beijing Huayue Education Technology Co., Ltd. All rights reserved.
//

#import "CodeInitViewController.h"
#import "XibInitViewController.h"

@interface CodeInitViewController ()

@end

@implementation CodeInitViewController

+(void)load {
    [super load];
    NSLog(@"codeVc---------%s",__func__);
}

+(void)initialize {
    [super initialize];
    NSLog(@"codeVc---------%s",__func__);
}

+(instancetype)alloc {
    NSLog(@"codeVc---------%s",__func__);
    return [super alloc];
}

- (nullable instancetype)initWithCoder:(NSCoder *)coder {
    NSLog(@"codeVc---------%s",__func__);
    return [super initWithCoder:coder];
}

- (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil {
    NSLog(@"codeVc---------%s",__func__);
    return [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
}

-(instancetype)init {
    NSLog(@"codeVc---------%s",__func__);
    return [super init];
}

- (void)loadView {
    [super loadView];
    NSLog(@"codeVc---------%s",__func__);
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor greenColor];
    self.title = @"codeVc";
    NSLog(@"codeVc---------%s",__func__);
}

- (void)viewWillAppear:(BOOL)animated  {
    [super viewWillAppear:animated];
    NSLog(@"codeVc---------%s",__func__);
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    NSLog(@"codeVc---------%s",__func__);
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    NSLog(@"codeVc---------%s",__func__);
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    NSLog(@"codeVc---------%s",__func__);
}

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];
    NSLog(@"codeVc---------%s",__func__);
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    NSLog(@"codeVc---------%s",__func__);
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    NSLog(@"codeVc---------%s",__func__);
}

-(void)dealloc {
    NSLog(@"codeVc---------%s",__func__);
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    //經過xib建立
    XibInitViewController *xibVc = [[XibInitViewController alloc] init];
    [self.navigationController pushViewController:xibVc animated:YES];
}

@end
View Code

XibInitViewController:對象

//
//  XibInitViewController.m
//  聲明週期
//
//  Created by 夏遠全 on 2019/11/3.
//  Copyright © 2019 Beijing Huayue Education Technology Co., Ltd. All rights reserved.
//

#import "XibInitViewController.h"

@interface XibInitViewController ()

@end

@implementation XibInitViewController

+(void)load {
    [super load];
    NSLog(@"xibVc---------%s",__func__);
}

+(void)initialize {
    [super initialize];
    NSLog(@"xibVc---------%s",__func__);
}

+(instancetype)alloc {
    NSLog(@"xibVc---------%s",__func__);
    return [super alloc];
}

- (nullable instancetype)initWithCoder:(NSCoder *)coder {
    NSLog(@"xibVc---------%s",__func__);
    return [super initWithCoder:coder];
}

- (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil {
    NSLog(@"xibVc---------%s",__func__);
    return [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
}

-(instancetype)init {
    NSLog(@"xibVc---------%s",__func__);
    return [super init];
}

- (void)loadView {
    [super loadView];
    NSLog(@"xibVc---------%s",__func__);
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor blueColor];
    self.title = @"xibVc";
    NSLog(@"xibVc---------%s",__func__);
}

- (void)viewWillAppear:(BOOL)animated  {
    [super viewWillAppear:animated];
    NSLog(@"xibVc---------%s",__func__);
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    NSLog(@"xibVc---------%s",__func__);
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    NSLog(@"xibVc---------%s",__func__);
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    NSLog(@"xibVc---------%s",__func__);
}

- (void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];
    NSLog(@"xibVc---------%s",__func__);
}

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    NSLog(@"xibVc---------%s",__func__);
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    NSLog(@"xibVc---------%s",__func__);
}

-(void)dealloc {
    NSLog(@"xibVc---------%s",__func__);
}


@end
View Code

 

3、註解blog

 +load: 程序啓動後,在系統的main函數調用以前,系統就會加載全部的load方法,提早進行一些資源包的配置或者hook,(能夠打斷點看看結果,本人親測過)
 
 +initialize: 當前類或者其子類未被初始化過期會首次調用,若之後當前類或者子類再屢次初始化時不會再調用,通常提早爲初始化作一些工做
 
 +alloc: 系統爲當前類分配內存時調用,在C語言中就是malloc這一步
 
 -initWithCoder: 經過storyBoard方式實例化的vc,須要通過反序列化,這個方法會被調用
 
 -initWithNibName:bundle: 經過xib文件或者init方法實例化的vc,這個方法都會被調用,其實init方法最終都會走該方法
 
 -init: 經過純代碼實例化Vc會調用,其最終會調用initWithNibName:bundle:方法
 
 -loadView: 實例化Vc後,能夠加載一些系統常規的View
 
 -viewDidLoad: 通常加載自定義的view或者初始化屬性,視圖加載完畢後會調用
 
 -viewWillAppear: 視圖即將出現會調用
 
 -viewWillDisappear: 視圖即將消失會調用
 
 -viewWillLayoutSubviews: 視圖加載完畢後即將要佈局
 
 -viewDidLayoutSubviews: 視圖加載完畢後佈局也完成了
 
 -didReceiveMemoryWarning: 加載視圖時,內存消耗太大,出現內存警告,會調用
 
 -dealloc: 實例化被銷燬,進行內存的回收會調用

 

4、演示教程

[1] 程序啓動,加載storyBoard實例化BoardInitViewController 生命週期

2019-11-03 16:23:45.724860+0800 聲明週期[6081:439250] codeVc---------+[CodeInitViewController load]
2019-11-03 16:23:45.725520+0800 聲明週期[6081:439250] boardVc---------+[BoardInitViewController load]
2019-11-03 16:23:45.725713+0800 聲明週期[6081:439250] xibVc---------+[XibInitViewController load]
2019-11-03 16:23:45.875841+0800 聲明週期[6081:439250] boardVc---------+[BoardInitViewController initialize]
2019-11-03 16:23:45.876016+0800 聲明週期[6081:439250] boardVc---------+[BoardInitViewController alloc]
2019-11-03 16:23:45.876132+0800 聲明週期[6081:439250] boardVc----------[BoardInitViewController initWithCoder:]
2019-11-03 16:23:45.932805+0800 聲明週期[6081:439250] boardVc----------[BoardInitViewController loadView] 2019-11-03 16:23:45.935257+0800 聲明週期[6081:439250] boardVc----------[BoardInitViewController viewDidLoad] 2019-11-03 16:23:45.935932+0800 聲明週期[6081:439250] boardVc----------[BoardInitViewController viewWillAppear:] 2019-11-03 16:23:45.938655+0800 聲明週期[6081:439250] boardVc----------[BoardInitViewController viewWillLayoutSubviews] 2019-11-03 16:23:45.938840+0800 聲明週期[6081:439250] boardVc----------[BoardInitViewController viewDidLayoutSubviews] 2019-11-03 16:23:45.960117+0800 聲明週期[6081:439250] boardVc----------[BoardInitViewController viewDidAppear:]

[2]  從BoardInitViewController中push到純代碼實例化的CodeInitViewController中

2019-11-03 16:26:21.027613+0800 聲明週期[6081:439250] codeVc---------+[CodeInitViewController initialize]
2019-11-03 16:26:21.027858+0800 聲明週期[6081:439250] codeVc---------+[CodeInitViewController alloc]
2019-11-03 16:26:21.027986+0800 聲明週期[6081:439250] codeVc----------[CodeInitViewController init]
2019-11-03 16:26:21.028089+0800 聲明週期[6081:439250] codeVc----------[CodeInitViewController initWithNibName:bundle:]
2019-11-03 16:26:21.032537+0800 聲明週期[6081:439250] codeVc----------[CodeInitViewController loadView]
2019-11-03 16:26:21.032821+0800 聲明週期[6081:439250] codeVc----------[CodeInitViewController viewDidLoad]
2019-11-03 16:26:21.032967+0800 聲明週期[6081:439250] boardVc----------[BoardInitViewController viewWillDisappear:]
2019-11-03 16:26:21.033095+0800 聲明週期[6081:439250] codeVc----------[CodeInitViewController viewWillAppear:]
2019-11-03 16:26:21.054149+0800 聲明週期[6081:439250] codeVc----------[CodeInitViewController viewWillLayoutSubviews]
2019-11-03 16:26:21.054325+0800 聲明週期[6081:439250] codeVc----------[CodeInitViewController viewDidLayoutSubviews]
2019-11-03 16:26:21.581912+0800 聲明週期[6081:439250] boardVc----------[BoardInitViewController viewDidDisappear:]
2019-11-03 16:26:21.582262+0800 聲明週期[6081:439250] codeVc----------[CodeInitViewController viewDidAppear:]

[3]  從CodeInitViewController中push到Xib實例化的XibInitViewController中

2019-11-03 17:03:12.506639+0800 聲明週期[6437:478856] codeVc---------+[CodeInitViewController alloc]
2019-11-03 17:03:12.506831+0800 聲明週期[6437:478856] codeVc----------[CodeInitViewController init]
2019-11-03 17:03:12.507020+0800 聲明週期[6437:478856] codeVc----------[CodeInitViewController initWithNibName:bundle:]
2019-11-03 17:03:12.508456+0800 聲明週期[6437:478856] codeVc----------[CodeInitViewController loadView]
2019-11-03 17:03:12.509038+0800 聲明週期[6437:478856] codeVc----------[CodeInitViewController viewDidLoad]
2019-11-03 17:03:12.509353+0800 聲明週期[6437:478856] boardVc----------[BoardInitViewController viewWillDisappear:]
2019-11-03 17:03:12.509780+0800 聲明週期[6437:478856] codeVc----------[CodeInitViewController viewWillAppear:]
2019-11-03 17:03:12.520785+0800 聲明週期[6437:478856] codeVc----------[CodeInitViewController viewWillLayoutSubviews]
2019-11-03 17:03:12.521002+0800 聲明週期[6437:478856] codeVc----------[CodeInitViewController viewDidLayoutSubviews]
2019-11-03 17:03:13.023817+0800 聲明週期[6437:478856] boardVc----------[BoardInitViewController viewDidDisappear:]
2019-11-03 17:03:13.024016+0800 聲明週期[6437:478856] codeVc----------[CodeInitViewController viewDidAppear:]

[4]  將XibInitViewController進行Pop後

2019-11-03 16:38:55.287065+0800 聲明週期[6081:439250] xibVc----------[XibInitViewController viewWillDisappear:]
2019-11-03 16:38:55.287238+0800 聲明週期[6081:439250] codeVc----------[CodeInitViewController viewWillAppear:]
2019-11-03 16:38:55.803065+0800 聲明週期[6081:439250] xibVc----------[XibInitViewController viewDidDisappear:]
2019-11-03 16:38:55.803504+0800 聲明週期[6081:439250] codeVc----------[CodeInitViewController viewDidAppear:]
2019-11-03 16:38:55.803857+0800 聲明週期[6081:439250] xibVc----------[XibInitViewController dealloc]

[5] 將CodeInitViewController進行Pop後

2019-11-03 16:40:07.038091+0800 聲明週期[6081:439250] codeVc----------[CodeInitViewController viewWillDisappear:]
2019-11-03 16:40:07.038281+0800 聲明週期[6081:439250] boardVc----------[BoardInitViewController viewWillAppear:]
2019-11-03 16:40:07.543910+0800 聲明週期[6081:439250] codeVc----------[CodeInitViewController viewDidDisappear:]
2019-11-03 16:40:07.544089+0800 聲明週期[6081:439250] boardVc----------[BoardInitViewController viewDidAppear:]
2019-11-03 16:40:07.544236+0800 聲明週期[6081:439250] codeVc----------[CodeInitViewController dealloc]

 

4、總結 

  • 程序一啓動,系統在當前應用程序的全部方法被調用以前優先加載load方法;
  • 控制器生命的正常流程是:初始化--->加載視圖--->將要顯示---->佈局子視圖---->徹底顯示---->將要顯示---->徹底消失----->對象銷燬(有可能內存警告釋放)
  • 控制器交互的先後顯隱流程是交叉的,在源VC即將消失和目的VC即將顯示以後,目的VC會完成全部子視圖的佈局,而後源VC纔會真正消失目的VC真正顯示
  • 控制器交互消失的流程也是交叉的,目的VC即將消失,源VC即將顯示,目的VC徹底消失,源VC徹底顯示,接着釋放目的VC
  • 經過stroyBoard建立的VC必定須要反序列化
  • 經過純代碼和xib建立的VC,最終都會調用initWithNibName:bundle:方法
相關文章
相關標籤/搜索