关于iOS 中UIViewController的生命周期以及相关视图(View)的探讨
2016-07-16 15:28
495 查看
最近朋友在面试的时候,面试官问到了关于iOS中UIViewController的生命周期以及相关视图(View)的问题,朋友对于自己的观点还是挺有信心的,但是面试官提出了异议,朋友回来便和我们聊起了此事,自己感觉面试官的回答有些问题,特在此发表以下本人对以上问题的理解。
1 先看一下有关的方法,相信大家都在熟悉不过
2 详细介绍loadView方法
调用loadView方法来生成UIViewController.view,如果loadView不能生成UIViewController.view,系统将会反复调用loadView及viewDidLoad方法, 并且最终调用[super loadView] 方法返回UIViewController.view
我们知道,当我们从StoryBoard中加载ViewController时,我们在Controller中拖拽的视图是可以被初始化的,这里面有一点需要我们注意,如果我们需要向controller中视图进行传值设置,通过以下方法得到的Controller中,视图还没有被初始化创建出来
我们可以在ViewController2的storyBoard中拉一个label,然后关联到头文件中,会发现我们得到controller时,里面的视图对象并没有进行创建:
可以想象,如果我们这时候需要对label进行一些属性设置,必然失败。
有人提出可以在创建后,手动调以下loadView方法,我们试一下手动调用loadView后,label是被创建了出来,但是暴漏了一个更严重的问题,系统不在调用ViewDidLoad方法,这是十分有风险的,因为我们大部分的初始化代码都会放在这个方法里,所以手动调用loadView是一种错误的方法,apple文档声明对于loadView方法,我们从来都不要手动直接调用,那么我们如何实现创建后对成员对象进行传值设置呢?
iOS9中增加了这样一个方法:
这个方法十分有用,调用这个方法,会将视图创建出来,并且不会忽略viewDidLoad的调用。
在iOS9中,UIViewController还增加了下面一个布尔值的属性,可以用来判断controller的view是否已经加载完成:
3 注意点
当程序收到内存不足的警告后, 程序内存中的所有的UIViewController都将会收到didReceiveMemoryWarning调用消息,我们要在这个方法里面做相应的处理 目的是将当前不显示的UIViewController中的view释放掉(不会调用UIViewController的dealloc方法), 所以当该UIViewController再次显示的时候又要生成一次, 此时它会调用loadView-> viewDidLoad ->viewWillAppear等, 这时最容易造成内存泄漏!
4 总结
@ initialize函数并不会每次创建对象都调用,只有在这个类第一次创建对象时才会调用,做一些类的准备工作,再次创建这个类的对象,initalize方法将不会被调用,对于这个类的子类,如果实现了initialize方法,在这个子类第一次创建对象时会调用自己的initalize方法,之后不会调用,如果没有实现,那么它的父类将替它再次调用一下自己的initialize方法,以后创建也都不会再调用。因此,如果我们有一些和这个相关的全局变量,可以在这里进行初始化。
@ init方法和initCoder方法相似,只是被调用的环境不一样,如果用代码进行初始化,会调用init,从nib文件或者归档进行初始化,会调用initCoder。
@ loadView方法是开始加载视图的起始方法,除非手动调用,否则在ViewController的生命周期中没特殊情况只会被调用一次。
@ viewDidLoad方法是我们最常用的方法的,类中成员对象和变量的初始化我们都会放在这个方法中,在类创建后,无论视图的展现或消失,这个方法也是只会在将要布局时调用一次。
@ viewWillAppare:视图将要展现时会调用。
@ viewWillLayoutSubviews:在viewWillAppare后调用,将要对子视图进行布局。
@ viewDidLayoutSubviews:已经布局完成子视图。
@ viewDidAppare:视图完成显示时调用。
@ viewWillDisappare:视图将要消失时调用。
@ viewDidDisappare:视图已经消失时调用。
@ dealloc:controller被释放时调用。
1 先看一下有关的方法,相信大家都在熟悉不过
//类的初始化方法 + (void)initialize; //对象初始化方法(代码创建) - (instancetype)init; //当用代码创建UIViewController的时候,[[UIViewController alloc] init],此时系统会调用此方法,查看有没有相应的xib文件,如果没有,则会创建相应的UIViewController -(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil; //当从xib加载视图控制器时会调用此方法,但是此时视图控制器上的相关控件还没有创建出来,为nil -(void)awakeFromNib; //从归档初始化(从storyBoard加载)会调用此方法 - (instancetype)initWithCoder:(NSCoder *)coder; //加载视图 -(void)loadView; //加载视图完毕 - (void)viewDidLoad; //将要布局子视图 -(void)viewWillLayoutSubviews; //已经布局子视图 -(void)viewDidLayoutSubviews; //已经展示 -(void)viewDidAppear:(BOOL)animated; //将要展示 -(void)viewWillAppear:(BOOL)animated; //将要消失 -(void)viewWillDisappear:(BOOL)animated; //已经消失 -(void)viewDidDisappear:(BOOL)animated; //内存警告 - (void)didReceiveMemoryWarning; //被释放 -(void)dealloc; //已经废除 - (void)viewWillUnload //已经废除 - (void)viewDidUnload
2 详细介绍loadView方法
调用loadView方法来生成UIViewController.view,如果loadView不能生成UIViewController.view,系统将会反复调用loadView及viewDidLoad方法, 并且最终调用[super loadView] 方法返回UIViewController.view
我们知道,当我们从StoryBoard中加载ViewController时,我们在Controller中拖拽的视图是可以被初始化的,这里面有一点需要我们注意,如果我们需要向controller中视图进行传值设置,通过以下方法得到的Controller中,视图还没有被初始化创建出来
我们可以在ViewController2的storyBoard中拉一个label,然后关联到头文件中,会发现我们得到controller时,里面的视图对象并没有进行创建:
可以想象,如果我们这时候需要对label进行一些属性设置,必然失败。
有人提出可以在创建后,手动调以下loadView方法,我们试一下手动调用loadView后,label是被创建了出来,但是暴漏了一个更严重的问题,系统不在调用ViewDidLoad方法,这是十分有风险的,因为我们大部分的初始化代码都会放在这个方法里,所以手动调用loadView是一种错误的方法,apple文档声明对于loadView方法,我们从来都不要手动直接调用,那么我们如何实现创建后对成员对象进行传值设置呢?
iOS9中增加了这样一个方法:
这个方法十分有用,调用这个方法,会将视图创建出来,并且不会忽略viewDidLoad的调用。
在iOS9中,UIViewController还增加了下面一个布尔值的属性,可以用来判断controller的view是否已经加载完成:
3 注意点
当程序收到内存不足的警告后, 程序内存中的所有的UIViewController都将会收到didReceiveMemoryWarning调用消息,我们要在这个方法里面做相应的处理 目的是将当前不显示的UIViewController中的view释放掉(不会调用UIViewController的dealloc方法), 所以当该UIViewController再次显示的时候又要生成一次, 此时它会调用loadView-> viewDidLoad ->viewWillAppear等, 这时最容易造成内存泄漏!
4 总结
@ initialize函数并不会每次创建对象都调用,只有在这个类第一次创建对象时才会调用,做一些类的准备工作,再次创建这个类的对象,initalize方法将不会被调用,对于这个类的子类,如果实现了initialize方法,在这个子类第一次创建对象时会调用自己的initalize方法,之后不会调用,如果没有实现,那么它的父类将替它再次调用一下自己的initialize方法,以后创建也都不会再调用。因此,如果我们有一些和这个相关的全局变量,可以在这里进行初始化。
@ init方法和initCoder方法相似,只是被调用的环境不一样,如果用代码进行初始化,会调用init,从nib文件或者归档进行初始化,会调用initCoder。
@ loadView方法是开始加载视图的起始方法,除非手动调用,否则在ViewController的生命周期中没特殊情况只会被调用一次。
@ viewDidLoad方法是我们最常用的方法的,类中成员对象和变量的初始化我们都会放在这个方法中,在类创建后,无论视图的展现或消失,这个方法也是只会在将要布局时调用一次。
@ viewWillAppare:视图将要展现时会调用。
@ viewWillLayoutSubviews:在viewWillAppare后调用,将要对子视图进行布局。
@ viewDidLayoutSubviews:已经布局完成子视图。
@ viewDidAppare:视图完成显示时调用。
@ viewWillDisappare:视图将要消失时调用。
@ viewDidDisappare:视图已经消失时调用。
@ dealloc:controller被释放时调用。
相关文章推荐
- Servlet3.1应用生命周期事件 (转载)
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- Android中进程生命周期的优先级
- android横竖屏切换时候Activity的生命周期
- android生命周期深入分析(一)
- IIS处理Asp.net请求和Asp.net页面生命周期说明
- ASP.NET Web页生命周期和执行的方法介绍
- 讲解iOS开发中基本的定位功能实现
- iOS中定位当前位置坐标及转换为火星坐标的方法
- js判断客户端是iOS还是Android等移动终端的方法
- iOS应用开发中AFNetworking库的常用HTTP操作方法小结
- iOS应用中UISearchDisplayController搜索效果的用法
- iOS App开发中的UISegmentedControl分段组件用法总结
- IOS开发环境windows化攻略