转自: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测试

最新文章

  1. [LeetCode] Length of Last Word 求末尾单词的长度
  2. DBlink与同义词
  3. css3中的字体样式
  4. MAS 移动业务整合系统
  5. 用Word收集网页中的内容,用文档结构图整理
  6. JAVA的覆盖、继承和多态的详细解说.this和super的用法
  7. HW2.9
  8. 实现Android 版网页快照功能
  9. hadoop深入研究:(十六)——Avro序列化与反序列化
  10. java中的vo、dto 、dao
  11. Linux工具之bc计算器进制的转换
  12. vue + BMap实现常用地图
  13. struts转发和重定向action
  14. 20155226 《网络攻防》 Exp1 PC平台逆向破解(5)M
  15. EZ 2018 04 21 NOIP2018 模拟赛(九)
  16. spring-mvc集成 swagger
  17. python 爬虫资料
  18. User-Defined Table Types 用户自定义表类型
  19. Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
  20. Read from socket failed: Connection reset by peer 问题

热门文章

  1. CloudStack 4.0.2 vRouter导致重启后状态不正常
  2. ECMAScript新特性【一】--Object.create
  3. vs开发工具报错:参数错误 异常来自 HRESULT:0x80070057 E_INVALIDARG
  4. C语言不定参数
  5. Orchard运用 - 定制呈现最新博客文章
  6. RV BaseRecyclerViewAdapterHelper 总结 MD
  7. JWT token心得
  8. 使用apache-cxf-2.2.10来制作一个极简版WebService程序
  9. Java保存简单偏好的类
  10. poj 3237(树链剖分+线段树)