IOS viewDidLoad方法被执行两次(viewDidLoad和loadView方法详解)
2016-03-23 10:58
411 查看
为了搞清楚viewDidLoad、loadView等方法的用途和调用顺序,写了一个小demo,不料viewDidLoad方法被执行了两次,模拟器也一直是黑屏。查看了这两个方法的官方解释后找到了错误原因和解决方法。
首先来看UIViewController.h文件中对viewDidLoad方法的解释:
?
接下来是对loadView方法的解释:
?
无论是从xib文件中加载视图,还是自己创建视图,viewDidLoad方法都会被调用,而且都是在视图已经被加载后调用,所以这里可以明确的一点是,任何UI控件的创建都不应该在viewDidLoad方法中被实现,因为这是xib文件或者loadView方法的任务。viewDidLoad只是通过nib或者loadView方法加载视图的一周拓展和补充机制,比如一些不方便通过nib设置的属性或是临时需要进行处理的控件内容。
至于loadView方法和xib文件的关系,个人的理解是:真正的UI控件的创建,都是要通过调用loadView中的代码来实现的,只不过在xib文件中,这些代码以xml格式的文档被保存,并且苹果通过storyboard解析这个xml文档,形成了一个可视化的图形界面。这是两者的共同点,至于不同点,官方文档中的解释已经很清楚了,一旦调用了loadView方法就意味着不是用nib文件。这就意味着loadView和xib文件不兼容。loadView具有更高的优先级。
下面通过几个实验来证明以上观点。
实验1:
创建一个空的工程文件,在viewDidLoad函数中写入简单的一行代码:
?
实验结果:运行程序后发现:控制台输出一行结果“123”。模拟器显示一个纯白色的界面。
实验分析:控制台的结果非常容易理解。但是我们并没有创建一个UIView或者设置它的背景颜色,系统是怎么创建我们在模拟器中看到的内容的呢?
答案是,如果我们不实现loadView方法,系统会默认我们不适用自定义的方式创建view而是从nib文件中加载。这时候就回去storyboard或者其他相应的nib文件中去寻找加载视图的代码。由于默认的ViewController类在main.storyboard中有自己的nib文件,所以可以成功的加载一个UIView。
实验2:
实现一个空的loadView方法:
?
实验结果:运行程序后发现,控制台输出两行“123”,模拟器黑屏。
实验分析:模拟器黑屏非常容易理解,因为我们实现了loadView方法,编译器以为我们要自定义一个UIView对象,从而去执行loadView方法中的代码,试图创建一个UIView,但是显然这样做会失败,所以得到一个黑色的(没有任何内容)的界面。至于为什么viewDidLoad方法会被调用两次,原因并不清楚(希望读到此处的大牛留言指教)。
实验三:
实现完整的loadView方法:
?
实验结果:同实验1的结果
实验分析:实现了一个完整的UIView的创建过程,与通过nib文件创建非常类似。
通过以上几个实验得出以下结论:
1.如果想要通过自定义的代码创建UIView,把这些代码都写入loadView方法里面去。
2.希望通过nib文件创建UIView的话,不要重写loadView方法。
3.viewDidLoad方法被执行两次很有可能是重写了一个不完整的loadView方法导致的 。
首先来看UIViewController.h文件中对viewDidLoad方法的解释:
?
?
至于loadView方法和xib文件的关系,个人的理解是:真正的UI控件的创建,都是要通过调用loadView中的代码来实现的,只不过在xib文件中,这些代码以xml格式的文档被保存,并且苹果通过storyboard解析这个xml文档,形成了一个可视化的图形界面。这是两者的共同点,至于不同点,官方文档中的解释已经很清楚了,一旦调用了loadView方法就意味着不是用nib文件。这就意味着loadView和xib文件不兼容。loadView具有更高的优先级。
下面通过几个实验来证明以上观点。
实验1:
创建一个空的工程文件,在viewDidLoad函数中写入简单的一行代码:
?
实验分析:控制台的结果非常容易理解。但是我们并没有创建一个UIView或者设置它的背景颜色,系统是怎么创建我们在模拟器中看到的内容的呢?
答案是,如果我们不实现loadView方法,系统会默认我们不适用自定义的方式创建view而是从nib文件中加载。这时候就回去storyboard或者其他相应的nib文件中去寻找加载视图的代码。由于默认的ViewController类在main.storyboard中有自己的nib文件,所以可以成功的加载一个UIView。
实验2:
实现一个空的loadView方法:
?
实验分析:模拟器黑屏非常容易理解,因为我们实现了loadView方法,编译器以为我们要自定义一个UIView对象,从而去执行loadView方法中的代码,试图创建一个UIView,但是显然这样做会失败,所以得到一个黑色的(没有任何内容)的界面。至于为什么viewDidLoad方法会被调用两次,原因并不清楚(希望读到此处的大牛留言指教)。
实验三:
实现完整的loadView方法:
?
实验分析:实现了一个完整的UIView的创建过程,与通过nib文件创建非常类似。
通过以上几个实验得出以下结论:
1.如果想要通过自定义的代码创建UIView,把这些代码都写入loadView方法里面去。
2.希望通过nib文件创建UIView的话,不要重写loadView方法。
3.viewDidLoad方法被执行两次很有可能是重写了一个不完整的loadView方法导致的 。
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 讲解iOS开发中基本的定位功能实现
- iOS中定位当前位置坐标及转换为火星坐标的方法
- js判断客户端是iOS还是Android等移动终端的方法
- iOS应用中UISearchDisplayController搜索效果的用法
- IOS开发环境windows化攻略
- iOS应用中UITableView左滑自定义选项及批量删除的实现
- 浅析iOS应用开发中线程间的通信与线程安全问题
- 检测iOS设备是否越狱的方法
- .net平台推送ios消息的实现方法
- 探讨Android与iOS,我们将何去何从?
- Android、iOS和Windows Phone中的推送技术详解
- iOS推送的那些事
- IOS 改变键盘颜色代码