转自:http://justsee.iteye.com/blog/1626231

众所周知,IB在加载nib的过程中存在着一些undocument行为,有的行为确实是不可理喻的,因此程序员对IB产生了抗拒心理。

今天我们要介绍的是IB导致的一个奇特行为。通过本文的描述, 作者完美地展示了IB给面向对象所带来的破坏作用。

我们有两个View Controller,暂名为superclass和subclass。subclass继承了superclass。

在superclass的initWithNibName初始化方法中:

  1. self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  2. if (self) {
  3. [self setWords:@”somebody is knocking”];
  4. }
  5. return self;

在superclass的viewDidLoad方法中:

  1. [super viewDidLoad];
  2. NSLog(@"get XXX:%@", [self words]);

然后我们用subclass继承superclass。在initWithNibName方法中:

  1. self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  2. if (self) {[
  3. [self setWords:@” pleaseanswer the door”];
  4. }

很显然,我们通过覆盖initWithNibName方法,修改了从superclass继承来的words属性。如果我们想打印pleaseanswer the door这段文本,你可能会想重用superclass的viewDidLoad方法:

  1. - (void)viewDidLoad{
  2. [super viewDidLoad];
  3. }

好了,运行程序。在加载superclass.xib时,控制台将打印somebodyis knocking。而加载subclass.xib时,控制台会打印pleaseanswer the door。

Hey,等一等。为什么我会在两个ViewController中都看到了somebody is knocking?

不用看了,subclass对象的words属性确实是please answer the door。如果你正在调试代码,那么可以debug区中确认这一点。

问题在于subclass的初始化出现了问题。看这一句:self=[super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

这句代码将导致IB加载nib文件,并立即调用viewDidLoad方法。我们可以看到在初始化subclass时的调用顺序如下:

1. subclass->initWithNibName

2. superclass->initWithNibName

3. superclass->setWords

4. subclass->viewDidLoad

5. superclass->initWithNibName

6. subclass->setProperty

让我再解释一下:

1. 首先subclass的initWithNIbName方法调用。

2. 接着调用superclass的initWithNibName方法。

3. 在superclass的initWithNibName方法中,words属性被设置为somebodyis knoking。

4. superclass的initWithNibName方法结束,表示nib文件已加载,则调用nib文件的File’sowner所指向的 viewDidLoad方法。注意,这时的nib文件名应为subclass.nib,于是应调用[subclass viewDidLoad]方法。

5. subclass的viewDidLoad方法又调用了supclass的viewDidLoad方法。于是控制台打印出的是words属性的当前值somebodyis knoking。

6. 最后才是initWithNibName方法剩余的代码,在这里我们将words属性修改为pleaseanswer the door。但为时已晚,在此之前viewDidLoad已经执行结束。

解决的办法是简单的,不要在initWithName方法中修改从父类继承来的属性,相反,我们可以在[super iewDidLoad]之前这样做:

- (void)viewDidLoad{

[selfsetWords:@” pleaseanswer the door”];

[super viewDidLoad];

}

结论

由于initWithNibName或者是IB 这些限制,.nib文件违反了面向对象的原则。.nib文件无法从另一个.nib文件继承。不管你的类如何继承,但nib文件中不会保存类的层次结构,File’sowner也无法指向类链。

thx:http://blog.csdn.net/kmyhy/article/details/7236619

btw:

现在是

1. subclass->initWithNibName

2. superclass->initWithNibName

3. superclass->setWords

4. subclass->setWords

5. subclass->viewDidLoad

6. superclass->viewDidLoad

打印:在加载superclass.xib时,控制台将打印somebodyis knocking。而加载subclass.xib时,控制台会打印pleaseanswer the door。

以上ios6测试

initWithNibName和viewDidLoad执行顺序的更多相关文章

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

    转载自:http://www.java123.net/v/380331.html 一个ViewController,一般通过init或initWithNibName来加载.二者没有什么不同,init最 ...

  2. UIViewController的生命周期及iOS程序执行顺序

    UIViewController的生命周期及iOS程序执行顺序     当一个视图控制器被创建,并在屏幕上显示的时候. 代码的执行顺序1. alloc                         ...

  3. iOS程序的执行顺序 和 UIViewController的生命周期

    iOS程序的执行顺序 1 进入程序的入口 进入main函数, 设置AppDelegate称为函数的代理 2  程序完成加载 -[AppDelegate application:didFinishLau ...

  4. iOS程序执行顺序 AppDelegate及 UIViewController 的生命周期

    iOS程序的启动执行顺序 AppDelegate 及 UIViewController 的生命周期 iOS应用程序的状态切换很重要,而UIViewControler对于iOS这种MVC模式来说尤为重要 ...

  5. UIViewController的生命周期及iOS程序执行顺序 和ios6 处理内存警告

    当一个视图控制器被创建,并在屏幕上显示的时候. 代码的执行顺序1. alloc                                   创建对象,分配空间2.init (initWithN ...

  6. iOS程序执行顺序和UIViewController 的生命周期(整理)

    说明:此文是自己的总结笔记,主要参考: iOS程序的启动执行顺序 AppDelegate 及 UIViewController 的生命周期 UIView的生命周期 言叶之庭.jpeg 一. iOS程序 ...

  7. Java的初始化块、静态初始化块、构造函数的执行顺序及用途探究

    Java与C++有一个不同之处在于,Java不但有构造函数,还有一个”初始化块“(Initialization Block)的概念.下面探究一下它的执行顺序与可能的用途. 执行顺序 首先定义A, B, ...

  8. MonoBehaviour Lifecycle(生命周期/脚本执行顺序)

    脚本执行顺序 前言 搭建一个示例来验证Unity脚本的执行顺序,大概测试以下部分: 物理方面(Physics) 渲染(Scene rendering) 输入事件(InputEvent) 流程图 Uni ...

  9. Unity中脚本的执行顺序总结(@WhiteTaken)

    (Editor)以上是Unity官方文档中的截图,脚本在被挂载到物体上,会启用Editor的方法Reset. (Initialization)当执行脚本开始,初始化的过程中,依次执行的是Awake-& ...

随机推荐

  1. C99规范

    . 增加restrict指针 C99中增加了公适用于指针的restrict类型修饰符,它是初始访问指针所指对象的惟一途径,因此只有借助restrict指针表达式才能访问对象.restrict指针指针主 ...

  2. Nginx发展现状及未来特性

    Nginx ("engine x")是一个高性能的HTTP和反向代理 服务器,也是一个IMAP/POP3/SMTP 代理服务器,其特点是占用内存少,并发能力强.到目前完为止,Ngi ...

  3. UVA 11107(Life Forms-后缀数组+二分)

    Problem C: Life Forms You may have wondered why most extraterrestrial life forms resemble humans, di ...

  4. 集成禅道和svn

    转载:http://www.zentao.net/book/zentaopmshelp/137.html 说明:svn集成功能配置会比较复杂,我们会尽量通过文档来帮助大家配置成功!如果实在配置不成功的 ...

  5. Orchard运用 - 学习资源分享

    这段时间研究Orchard,看到一些资源十分有用. 比如国内还是有些牛人在分享心得,在此也广播一下给新手: JustRun对Orchard的一些代码分析 Orchard源码分析 Orchard中文社区 ...

  6. 通过Spring配置文件中bean中的property赋值

    基本数据类型赋值-通过spring配置文件中bean中的property 扩展-以此方式可以通过配置为连接数据的属性赋值 1.如果是基本数据类型,可以通过setter方法为对象中的属性设置初始值,应用 ...

  7. Thinkphp学习笔记-模板主题

    一个模块如果需要支持多套模板文件的话,就可以使用模板主题功能. 默认情况下,没有开启模板主题功能,如果需要开启,设置 DEFAULT_THEME 参数即可: // 设置默认的模板主题 'DEFAULT ...

  8. Sqlserver DateTime转换成SMALLDATETIME时“产生一个超出范围的值”

    工作中遇到一个问题,A表中字段(DateTime1)的数据类型为DateTime,新建了一张表B的SMALLDATETIME1字段的数据来自A表的DateTime1 但在将A表字段DateTime1导 ...

  9. HYSBZ 1012 最大数maxnumber

    思路:在单调队列不更新列首.由于查询区间大小不确定,所以不能保证下次是否还用到它 #include <cstdio> #include <cstring> #include & ...

  10. Jquery Validate结合QTip实现绚丽的表单验证

    相信做过前端开发的童鞋,一定都涉及到表单验证的模块设计,也定都会对Alert的粗暴提示厌恶至极.当然,我也不例外.一直期待着,一种比较优雅提示效果. 看到这,大家可能觉得Jquery Validate ...