initWithNibName与viewDidLoad的执行关系以及顺序

转载自:http://www.java123.net/v/380331.html

一个ViewController,一般通过init或initWithNibName来加载。二者没有什么不同,init最终还是要调用initWithNibName方法(除非这个ViewController没有nib文件)。 我们经常在initWithNibName方法中初始化视


一个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时执行)。

时间: 2024-08-09 10:33:07

initWithNibName与viewDidLoad的执行关系以及顺序的相关文章

【原】不定义Order属性,通过切面类的定义顺序来决定通知执行的先后顺序

[结论] 若不同切面类执行时,在没有定义“order属性”,而且切面类中触发增强通知的切入点都相同,则在切面类中的通知的执行顺序与该切面类在<aop:config>元素中“声明的顺序”相关,即先声明的切面类先执行,后声明的切面类后执行. [代码示例] 1 <aop:config> 2 <!-- 用户自定义的切面01,用于不同切面类执行顺序的测试 --> 3 <aop:aspect id="myMethod01Aspect" ref="

Unity3D 中脚本执行的先后顺序

Unity3D本身自带有控制脚本执行先后顺序的方法: Edit ---> Project Settings ---> Script Execution Order  ---> 值越小脚本会越先被执行 Unity3D 中脚本执行的先后顺序,码迷,mamicode.com

【原】Order属性决定了不同切面类中通知执行的先后顺序

[障碍再现] MyBatis配置多数据源时,数据源切换失败. [原因分析]    自定义切面和Spring自带事务切面“即<aop:advisor>”执行的先后顺序导致数据源不能切换成功. [解决方案]1.配置代码 1 <aop:config> 2 <!-- 1.Spring框架自身提供的切面 --> 3 <aop:advisor advice-ref="userTxAdvice" pointcut="execution(public

ASP.NET中HttpApplication中ProcessRequest方法中执行的事件顺序;ASP.NET WebForm和MVC整体请求流程图

ASP.NET中HttpApplication中ProcessRequest方法中执行的事件顺序 1.BeginRequest  开始处理请求 2.AuthenticateRequest 授权验证请求,获取用户授权信息 3.PostAuthenticateRequest 获取成功 4.AunthorizeRequest 授权,一般来检查用户是否获得权限 5.PostAuthorizeRequest 获得授权 6.ResolveRequestCache 获取页面缓存结果(如果没有则执行) 7.Po

jsp页面中的代码执行加载顺序介绍(转)

原文出处:http://www.3lian.com/edu/2014/01-10/123053.html 本篇文章主要是对jsp页面中的代码执行加载顺序进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助 1. java是在服务器端运行的代码,jsp在服务器的servlet里运行,而javascript和html都是在浏览器端运行的代码.所以加载执行顺序是是java>jsp>js. 2. js在jsp中的加载顺序 页面上的js代码时html代码的一部分,所以页面加载的时候是由上而下加

Go ---- defer 和 return 执行的先后顺序

Go 中 defer 和 return 执行的先后顺序 多个defer的执行顺序为“后进先出”: defer.return.返回值三者的执行逻辑应该是:return最先执行,return负责将结果写入返回值中:接着defer开始执行一些收尾工作:最后函数携带当前返回值退出. 如果函数的返回值是无名的(不带命名返回值),则go语言会在执行return的时候会执行一个类似创建一个临时变量作为保存return值的动作,而有名返回值的函数,由于返回值在函数定义的时候已经将该变量进行定义,在执行retur

【iOS】init,loadView,viewDidLoad加载关系

一.loadView 永远不要主动调用这个函数.view controller会在view的property被请求并且当前view值为nil时调用这个函数.如果你手动创建view,你应该重载这个函数.如果你用IB创建view并初始化view controller,那就意味着你使用initWithNibName:bundle:方法,这时,你不应该重载loadView函数. 这个方法的默认实现是这样:先寻找有关可用的nib文件的信息,根据这个信息来加载nib文件,如果没有有关nib文件的信息,默认实

多表查询,子查询,及查询语句中语句执行的先后顺序和特点

对多张表进行查询操作 查询方式1: 笛卡尔积查询 select * from 表1,表2; 结果:让表1中的每一条记录和表2中每一条记录一次组合 表1 n条记录 表2 m条记录 最终查询结果:n * m 条 注意: 1.观察笛卡尔积查询的最终结果,很多数据没有实际作用 2.查询结果太多,对内存压力大 笛卡尔积查询优化(内连接) 加上条件 隐式内连接 select * from 表1,表2 where 表1.字段 = 表2.字段; 显示内连接语法 select * from 表1 inner jo

__destruct与register_shutdown_function执行的先后顺序问题

根据php手册的解析. __destruct是 析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行. 而register_shutdown_function是 Registers a callback to be executed after script execution finishes or exit() is called. 注册一个回调函数,此函数在脚本运行完毕或调用exit()时执行. 从字面上理解,__destruct是对象层面的,而register_shutdo