一个ViewController,一般通过init或initWithNibName来加载。二者没有什么不同,init最终还是要调用initWithNibName方法(除非这个ViewController没有nib文件)。

我们经常在initWithNibName方法中初始化视图,变量或者其他成员。这是最常见的initWithNibName方法写法:

- (id)initWithNibName:(NSString *)nibNameOrNilbundle:(NSBundle *)nibBundleOrNil

{

self = [superinitWithNibName:nibNameOrNil bundle:nibBundleOrNil];

if (self) {

label=[[UILabelalloc]initWithFrame:

CGRectMake(0,0,160,160)];

[self.viewaddSubview:label];

...

}

returnself;

}

在if语句中,包含了最常见的成员初始化代码。

在这段代码中,如果你向ViewController的视图树中加入一些新的UIView子类,比如上面的代码:

[self.viewaddSubview:label];

这不会有什么问题。但是这会导致另一个方法的调用,即viewDidLoad方法。

viewDidLoad方法一般情况下只会在nib文件已载入内存(即视图树构建完成)之后调用。

但还有另一种情况,如果ViewController的view属性被引用时,view=nil,也会导致nib的加载行为,从而也导致viewDidLoad方法的调用。如果你在initWithNibName方法一直不引用view属性,则直至initWithNibName方法结束,viewDidLoad方法也不会触发。

你也许奇怪,如果在代码中你一直不引用这个ViewController的view属性怎么办?那么是不是viewDidLoad方法一直都不会调用了?

它会在ViewController对象第1次present时调用,比如你使用presentModalViewController或pushViewController方法弹出它。这两个方法同时还会调用ViewController的appear方法(即viewWillAppear方法和viewDidAppear方法)。

viewDidLoad方法会比appear方法要早执行(appear方法会导致一个弹出动画产生)。而且如果在present之前已经执行过viewDidLoad方法,则present方法不会触发viewDidLoad方法。

这就是为什么我们会奇怪viewDidLoad方法中的代码有时执行有时似乎不被执行的原因。其实根源还是在initWithNibName方法的if语句中。

如果你在initWithNibName时,引用了ViewController的view属性,由于此时view为nil,将触发nib文件的加载行为,导致viewDidLoad方法不等present就提前调用了。由于initWithNibName方法中ViewController成员还未初始化,导致任何对这些成员的引用都是无效的。

比如在viewDidLoad方法中,由于该方法提前执行,导致数据访问对象还是nil(initWithNibName仍然未执行完)。如果此时在viewDidLoad方法想通过数据访问对象获取表格数据,将得到空。这样从表面上看,viewDidLoad方法似乎未被执行。

这个情况可以通过两种方法来改进:

一、initWithNibName方法中,不要有任何成员初始化的代码。把这些代码移到viewDidLoad方法开始进行。

二、由于initWithNibName方法保证是在present方法中进行,我们也可以在initWithNibName方法中保留成员初始化代码。但把原来viewDidLoad方法中的代码移到appear方法中。也就是,最好不要在viewDidLoad方法中进行和成员初始化无关的事情。这样还有一个好处,每次presentViewController,都会执行appear方法中的代码(如果是viewDidLoad方法,则只会在加载nib时执行)。

loadview也是第1次引用ViewController的view属性(此时,view=nil)时调用,但在viewDidLoad之前。不同的是,loadview在view树构建前调用,viewDidLoad在view树构建完成后调用。二者之间,则进行nib的加载。因此,我们常在编程方式创建viewcontroller时重载loadview方法,因为本来就不需要加载nib的内容。

转:http://blog.sina.com.cn/s/blog_947c4a9f01015i23.html

[转]浅论ViewController的加载 -- 解决 viewDidLoad 被提前加载的问题(pushViewController 前执行)的更多相关文章

  1. 浅论ViewController的加载 -- 解决 viewDidLoad 被提前加载的问题(pushViewController 前执行)

    一个ViewController,一般通过init或initWithNibName来加载.二者没有什么不同,init最终还是要调用initWithNibName方法(除非这个ViewControlle ...

  2. iOS 解决LaunchScreen中图片加载黑屏问题

    iOS 解决LaunchScreen中图片加载黑屏问题 原文: http://blog.csdn.net/chengkaizone/article/details/50478045 iOS 解决Lau ...

  3. netload 加载程序集抛异常----无法加载程序集解决办法

    netload 加载程序集抛异常----无法加载程序集 错误信息如下: 无法加载程序集.错误详细信息: System.BadImageFormatException: 未能加载文件或程序集“file: ...

  4. [Android Pro] so 动态加载—解决sdk过大问题

    原文地址: https://blog.csdn.net/Rong_L/article/details/75212472 前言 相信Android 开发中大家或多或少都会集成一些第三方sdk, 而其中难 ...

  5. 使用Redirector插件解决googleapis公共库加载的问题【转】

    转自:http://www.cnblogs.com/kari/p/5860371.html 最近访问一些面向国外的网站总是会出现ajax.googleaips.com无法加载的情况.以下为加载stac ...

  6. 使用Redirector插件解决googleapis公共库加载的问题

    最近访问一些面向国外的网站总是会出现ajax.googleaips.com无法加载的情况.以下为加载stackoverflow时的情境: 图1 -无法加载的google公共库 问题的原因是谷歌没有在国 ...

  7. 过滤器解决hibernate中懒加载问题

    使用过滤器解决懒加载问题需要我们对过滤器的生命周期有深刻的理解 1.浏览器发送一个请求 2.请求通过过滤器执行dofilter之前的代码 3.浏览器通过过滤器到达Servlet(注意我们这里的serv ...

  8. 解决 Visual Studio 符号加载不完全问题

    解决 Visual Studio 符号加载不完全问题 工具 - 选项 - 搜索 "符号" - 选上服务器 | 加载所有符号, 之后符号就会显示完全

  9. 解决页面初始化vue加载代码问题

    <style type="text/css"> /* 解决页面初始化vue加载代码问题 */ [v-cloak] { display: none; } </sty ...

随机推荐

  1. linux挂载mount参数优化

    一. 1) 蓝色:表示经过优化的xfs mount时的参数defaults,noatime,nodiratime,nobarrier,discard,allocsize=256m,logbufs=8, ...

  2. UE没法远程修改文件

    UE没法远程修改文件修改ftp和sftp修改方式都没有作用,考虑可能是防火墙的作用,关闭防火墙可以.于是在控制面板->防火墙->修改策略中将UE的公用网络打开.

  3. MFC命名规范

    属性部分 全局变量:g_ 常量:c_ c++类成员变量:m_ 静态变量:s_ 类型部分 指针:p 函数:fn 无效:v 句柄:h 长整型:l 布尔:b 浮点型(有时也指文件):f 双字:dw 字符串: ...

  4. js文件的版本控制

    使用grunt完成requirejs的合并压缩和js文件的版本控制   最近有一个项目使用了 requirejs 来解决前端的模块化,但是随着页面和模块的越来越多,我发现我快要hold不住这些可爱的j ...

  5. 【AtCoder】ARC085

    C - HSI 题解 \(E = 1900 * (N - M) + 100 * M + \frac{1}{2^{M}} E\) \(E = 2^{M}(1900 * (N - M) + 100 * M ...

  6. Storm1.0.3集群部署

    Storm集群部署 所有集群部署的基本流程都差不多:下载安装包并上传.解压安装包并配置环境变量.修改配置文件.分发安装包.启动集群.查看集群是否部署成功. 1.所有的集群上都要配置hosts vi   ...

  7. ubuntu下wordcount例子

    在/home/yuanqin/下建立file文件夹,再在文件夹建立file1.txt.file2.txt.file3.txt file1内容:hello word file2内容:hello hado ...

  8. Wireshark网络分析就这么简单

    tcpdump抓包命令: root#tcpdump -I eth0 -s 80 -w /tmp/tcpdump.cap 注:其中80表示,只抓每个包的前80个字节. 抓包时就筛选自己需要的包: Wir ...

  9. 前馈神经网络练习:使用tensorflow进行葡萄酒种类识别

    数据处理 样本数据描述 样本数据集是double类型的178 * 14矩阵,第一列表示酒所属类别,后面13列分别表示当前样本的13个属性: 1) Alcohol 2) Malic acid 3) As ...

  10. app微信支付宝支付后台的插件模式+回调通过spring广播处理后续业务(已亲测可用)

    写在前面的话:每当我们做一个项目,基本上都会涉及到支付的业务,最常用的莫过于微信和支付宝的支付了,项目有bug,有问题,都不叫问题,可一旦钱出了问题,那就是大问题了,所以在支付业务上我们必须慎之又慎! ...