iOS之深入了解控制器View的加载
来源:互联网 发布:唱吧假唱软件 编辑:程序博客网 时间:2024/05/20 06:55
我们会遇到这样的问题,loadView有什么作用,它与viewDidLoad有何区别,首先我们得知道,控制器view是通过懒加载的方式进行加载的,即用到的时候再加载。
loadView方法
当我们用到控制器view时,就会调用控制器view的get方法,在get方法内部,首先判断view是否已经创建,如果已存在,则直接返回存在的view,如果不存在,则调用控制器的loadView方法,在控制器没有被销毁的情况下,loadView也可能会被执行多次
viewDidLoad方法
当控制器的loadView方法执行完毕,view被创建成功后,就会执行viewDidLoad方法,该方法与loadView方法一样,也有可能被执行多次。在开发中,我们可能从未遇到过执行多次的情况,那什么时候会执行多次呢?
比如A控制器push出B控制器,此时,窗口显示的是B控制器的view,此时如果收到内存警告,我们一般会将A控制器中没用的变量及view销毁掉,之后当我们从B控制器pop到A控制器时,就会再次执行A控制器的loadView方法与viewDidLoad方法。
1.通过storyboard加载
当控制器通过storyboard加载时,需要指定storyboard的名称,控制器view最终就是storyboard所描述的样子,这个比较简单,不做详细阐述
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"TestViewController" bundle:nil]; TestViewController *testVC = [storyboard instantiateInitialViewController]; [self.navigationController pushViewController:testVC animated:YES];}
2.通过xib加载
当控制器view通过xib加载的时候,可能会出现三种情况
a. 指定xib名称(OtherViewController.xib)
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ TestViewController *testVC = [[TestViewController alloc] initWithNibName:@"OtherViewController" bundle:nil]; [self.navigationController pushViewController:testVC animated:YES];}
当我们指定了xib的名称,loadView方法就会去加载对应的xib(OtherViewController.xib)
b.不指定xib名称1
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ TestViewController *testVC = [[TestViewController alloc] init]; [self.navigationController pushViewController:testVC animated:YES];}
如果我们不指定xib名称,loadView就会加载与控制器同名的xib(TestViewController.xib)
c.不指定xib名称2
我们先将TestViewController.xib这个文件删除掉,这个时候,我们再来运行程序
当没有指定xib名称,且没有与控制器同名的xib时,会加载前缀与控制器名相同而不带controller的xib(TestView.xib)。
3.不通过sb\xib加载
将TestView.xib这个文件也删除掉,再来运行程序,
4.重写loadView方法
我们重写TestViewController的loadView方法,里面不做任何事
- (void)loadView {}
结果跟上面一样黑,不同的是,这次并没有创建view,注意看上图最外层并不是UIView。
如果我们希望控制器view加载出来的时候不是UIView而是其他控件,比如UIImageView,那我们就可以重写loadView。
- (void)loadView{ self.view = [[UIImageView alloc] init];}
结论
1.重写loadView方法,则会根据重写的loadView方法创建view
2.控制器通过storyboard加载,则根据storyboard的描述创建view
3.控制器view通过xib加载,则根据nibName对应的xib创建view
4.没有指定nibName,则根据与控制器同名的xib创建view
5.没有同名的xib,则根据与控制器名前缀相同不带controller的xib创建view
6.如果都没有,则创建一个空白的xib
小细节
在上面的2、3两点结论中,不知道大家有没有一个疑问?
为什么上面是说的控制器,而下面却说的控制器view?
笔者结合控制器的awakeFromNib方法给大家说明一下这个问题。
顾名思义,当控制器从nib加载的时候就会调用这个方法。
先来看看通过storyboard加载的情况
//A控制器中代码- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"TestViewController" bundle:nil]; TestViewController *testVC = [storyboard instantiateInitialViewController]; [self.navigationController pushViewController:testVC animated:YES];}//B控制器中代码- (void)awakeFromNib { NSLog(@"B通过nib加载");}
控制台打印了“B通过nib加载”,即调用了B控制器的awakeFromNib方法。
将之前删除的TestViewController.xib文件重写添加进去,再来看通过xib加载的情况
//A控制器中代码改为如下- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ TestViewController *testVC =[[TestViewController alloc] init]; [self.navigationController pushViewController:testVC animated:YES];}//B控制器中代码不变
控制台没有任何输出,即B控制器的awakeFromNib方法并没有被调用。
结论
storyboard加载的是控制器及控制器view,而xib加载的仅仅只是控制器的view
最后给大家补充几个小的知识点
1.控制器view的生命周期:viewDidLoad -> viewWillAppear -> viewWillLayoutSubviews -> viewDidLayoutSubviews
-> viewDidAppear -> viewWillDisappear -> viewDidDisappear2.内存警告传递过程:手机内存不足产生事件->通知应用程序->调用应用程序代理方法->把事件传递给窗口->窗口传给控制器->调用控制器的内存警告方法
3.xib描述控制器view时,其File's Owner为对应的控制器类名,当通过xib自定义view或cell时,File's Owner不能是其类名,但可以是控制器的类名,总的来说File's Owner只能是控制器
- iOS之深入了解控制器View的加载
- iOS之深入了解控制器View的加载
- iOS之深入了解控制器View的加载
- iOS之深入了解控制器View的加载
- iOS之深入了解控制器View的加载
- ios深入了解控制器view的加载
- 【iOS开发-73】创建控制器的3种方式、深入了解view的创建和加载顺序
- view加载的深入了解
- iOS--控制器加载自定义view的xib
- iOS开发之控制器View的创建
- iOS之获取当前view的控制器
- iOS的控制器的view加载到另一个控制器的View以及手势问题的坑
- ios-day11-04(控制器view的创建与延迟加载)
- iOS中视图控制器View的加载与生命周期
- iOS中关于控制器view加载顺序的个人总结
- iOS 【通过sb加载描述window根控制器的view】
- iOS 【通过xib加载描述window根控制器的view】
- [iOS 转] xib文件加载控制器View的一些原理
- [Q学习]9 Qt事件系统——投递事件
- 单点触控
- db2笔记
- iOS开发------操作通讯录(AddressBook篇)&通讯录UI(AddressBookUI篇)
- 跨域问题
- iOS之深入了解控制器View的加载
- C#三十三 事务
- 【hdu4283】区间动态规划问题
- 小工具-使用java SSL通过url获得访问转为String-http/https
- java20函数的复写override
- Java垃圾收集器
- 3-5 数的拆分
- html5本地存储-遍历以及清空数据
- HDU2147(模拟找规律)