iOS对UIViewController生命周期和属性方法的解析(一)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: iOS对UIViewController生命周期和属性方法的解析

iOS对UIViewController生命周期和属性方法的解析


一、引言


       作为MVC设计模式中的C,Controller一直扮演着项目开发中最重要的角色,它是视图和数据的桥梁,通过它的管理,将数据有条有理的展示在我们的View层上。iOS中的UIViewController是UIKit框架中最基本的一个类。从第一个UI视图到复杂完整项目,都离不开UIViewController作为基础。基于UIViewController的封装和扩展,也能够出色的完成各种复杂界面逻辑。这篇博客,旨在讨论UIViewController的生命周期和属性方法,在最基础的东西上,往往会得到意想不到的惊喜。


二、UIViewController的生命周期


       要了解UIViewController,先要弄清楚其生命周期。在面向对象的语言中,是对象,就一定要有生命周期,UIViewController也不例外,生命周期管理Controller的作用范围和时间,也管理其内对象的作用范围和时间。首先,UIViewController中与其生命周期有关的几个函数如下:


//类的初始化方法

+ (void)initialize;

//对象初始化方法

- (instancetype)init;

//从归档初始化

- (instancetype)initWithCoder:(NSCoder *)coder;

//加载视图

-(void)loadView;

//将要加载视图

- (void)viewDidLoad;

//将要布局子视图

-(void)viewWillLayoutSubviews;

//已经布局子视图

-(void)viewDidLayoutSubviews;

//内存警告

- (void)didReceiveMemoryWarning;

//已经展示

-(void)viewDidAppear:(BOOL)animated;

//将要展示

-(void)viewWillAppear:(BOOL)animated;

//将要消失

-(void)viewWillDisappear:(BOOL)animated;

//已经消失

-(void)viewDidDisappear:(BOOL)animated;

//被释放

-(void)dealloc;

上面这么多的函数,乍一看什么复杂,其实关系什么明朗,除了initialize,init和initWithCoder不是存在所有对象的声明周期中,其他函数都会在UIViewController的声明周期中有序的被调用。那么具体的调用顺序是怎样的呢,最好的办法是实践一下,通过编号打印,结果如下:



这是一个ViewController完整的声明周期,其实里面还有好多地方需要我们注意一下:


1:initialize函数并不会每次创建对象都调用,只有在这个类第一次创建对象时才会调用,做一些类的准备工作,再次创建这个类的对象,initalize方法将不会被调用,对于这个类的子类,如果实现了initialize方法,在这个子类第一次创建对象时会调用自己的initalize方法,之后不会调用,如果没有实现,那么它的父类将替它再次调用一下自己的initialize方法,以后创建也都不会再调用。因此,如果我们有一些和这个相关的全局变量,可以在这里进行初始化。


2:init方法和initCoder方法相似,只是被调用的环境不一样,如果用代码进行初始化,会调用init,从nib文件或者归档进行初始化,会调用initCoder。


3:loadView方法是开始加载视图的起始方法,除非手动调用,否则在ViewController的生命周期中没特殊情况只会被调用一次。


4:viewDidLoad方法是我们最常用的方法的,类中成员对象和变量的初始化我们都会放在这个方法中,在类创建后,无论视图的展现或消失,这个方法也是只会在将要布局时调用一次。


5:viewWillAppear:视图将要展现时会调用。


6:viewWillLayoutSubviews:在viewWillAppear后调用,将要对子视图进行布局。


7:viewDidLayoutSubviews:已经布局完成子视图。


8:viewDidAppare:视图完成显示时调用。


9:viewWillDisappear:视图将要消失时调用。


10:viewDidDisappear:视图已经消失时调用。


11:dealloc:controller被释放时调用。


注意:经过测试,从nib文件加载的controller,只要不释放,在每次viewWillAppare时都会调用layoutSubviews方法,有时甚至会在viewDidAppare后在调用一次layoutSubviews,而重点是从代码加载的则只会在开始调用一次,之后都不会,所以注意,在layoutSubviews中写相关的布局代码十分危险。


三、从storyBoard加载UIViewController实例的传值陷阱


       我们知道,当我们从StoryBoard中加载ViewController时,我们在Controller中拖拽的视图是可以被初始化的,这里面有一点需要我们注意,如果我们需要向controller中视图进行传值设置,通过以下方法得到的Controller中,视图还没有被初始化创建出来:


ViewController2 * viewController2 = [[UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"ViewController2"];

我们可以在ViewController2的storyBoard中拉一个label,然后关联到头文件中,如下打印,会发现我们得到controller时,里面的视图对象并没有进行创建:


ViewController2 * viewController2 = [[UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]] instantiateViewControllerWithIdentifier:@"ViewController2"];

   NSLog(@"%@",viewController2.label);

   [self presentViewController:viewController2 animated:YES completion:nil];

打印如下:

image.png



可以想象,如果我们这时候需要对label进行一些属性设置,必然失败。有人提出可以在创建后,手动调以下loadView方法,我们试一下,结果如下:


image.png


可以看到,手动调用loadView后,label是被创建了出来,但是暴漏了一个更严重的问题,系统不在调用ViewDidLoad方法,这是十分有风险的,因为我们大部分的初始化代码都会放在这个方法里,所以手动调用loadView是一种错误的方法,apple文档声明对于loadView方法,我们从来都不要手动直接调用,那么我们如何实现创建后对成员对象进行传值设置呢,iOS9中增加了这样一个方法:


- (void)loadViewIfNeeded NS_AVAILABLE_IOS(9_0);

这个方法十分有用,调用这个方法,会将视图创建出来,并且不会忽略viewDidLoad的调用。


在iOS9中,UIViewController还增加了下面一个布尔值的属性,可以同来判断controller的view是否已经加载完成:


@property(nullable, nonatomic, readonly, strong) UIView *viewIfLoaded NS_AVAILABLE_IOS(9_0);

目录
相关文章
|
27天前
|
人工智能
歌词结构的巧妙安排:写歌词的方法与技巧解析,妙笔生词AI智能写歌词软件
歌词创作是一门艺术,关键在于巧妙的结构安排。开头需迅速吸引听众,主体部分要坚实且富有逻辑,结尾则应留下深刻印象。《妙笔生词智能写歌词软件》提供多种 AI 功能,帮助创作者找到灵感,优化歌词结构,写出打动人心的作品。
|
1月前
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
41 3
|
1月前
|
缓存 JavaScript 前端开发
Vue3与Vue2生命周期对比:新特性解析与差异探讨
Vue3与Vue2生命周期对比:新特性解析与差异探讨
92 2
|
28天前
|
人工智能
写歌词的技巧和方法全解析:开启你的音乐创作之旅,妙笔生词智能写歌词软件
怀揣音乐梦想,渴望用歌词抒发情感?掌握关键技巧,你也能踏上创作之旅。灵感来自生活点滴,主题明确,语言简洁,韵律和谐。借助“妙笔生词智能写歌词软件”,AI辅助创作,轻松写出动人歌词,实现音乐梦想。
|
13天前
|
JSON PHP 数据格式
PHP解析配置文件的常用方法
INI文件是最常见的配置文件格式之一。
|
19天前
|
机器学习/深度学习 人工智能 安全
TPAMI:安全强化学习方法、理论与应用综述,慕工大、同济、伯克利等深度解析
【10月更文挑战第27天】强化学习(RL)在实际应用中展现出巨大潜力,但其安全性问题日益凸显。为此,安全强化学习(SRL)应运而生。近日,来自慕尼黑工业大学、同济大学和加州大学伯克利分校的研究人员在《IEEE模式分析与机器智能汇刊》上发表了一篇综述论文,系统介绍了SRL的方法、理论和应用。SRL主要面临安全性定义模糊、探索与利用平衡以及鲁棒性与可靠性等挑战。研究人员提出了基于约束、基于风险和基于监督学习等多种方法来应对这些挑战。
40 2
|
27天前
|
安全 Java
Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧
【10月更文挑战第20天】Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧,包括避免在循环外调用wait()、优先使用notifyAll()、确保线程安全及处理InterruptedException等,帮助读者更好地掌握这些方法的应用。
17 1
|
1月前
|
存储 JavaScript 前端开发
Vue3权限控制全攻略:路由与组件层面的用户角色与权限管理方法深度解析
Vue3权限控制全攻略:路由与组件层面的用户角色与权限管理方法深度解析
116 2
|
12天前
|
存储 Kubernetes 调度
深度解析Kubernetes中的Pod生命周期管理
深度解析Kubernetes中的Pod生命周期管理
|
1月前
|
SQL 监控 数据库
SQL语句是否都需要解析及其相关技巧和方法
在数据库管理中,SQL(结构化查询语言)语句的使用无处不在,它们负责数据的查询、插入、更新和删除等操作

推荐镜像

更多
下一篇
无影云桌面