资源预览内容
第1页 / 共5页
第2页 / 共5页
第3页 / 共5页
第4页 / 共5页
第5页 / 共5页
亲,该文档总共5页全部预览完了,如果喜欢就下载吧!
资源描述
initWithNibName 导致的初始化问题众所周知,IB 在加载 nib 的过程中存在着一些 undocument 行为,有的行为确实是不可理喻的,因此程序员对 IB 产生了抗拒心理。今天我们要介绍的是 IB 导致的一个奇特行为。通过本文的描述, 作者完美地展示了 IB 给面向对象所带来的破坏作用。我们有两个 View Controller,暂名为 superclass 和 subclass。subclass 继承了superclass。在 superclass 的 initWithNibName 初始化方法中,我们这样写道:self = super initWithNibName:nibNameOrNil bundle:nibBundleOrNil;if (self) self setWords:”somebody is knocking”;return self;在 superclass 的 viewDidLoad 方法中,我们这样写:super viewDidLoad;NSLog(get XXX:%, self words);然后我们用 subclass 继承 superclass。在 initWithNibName 方法中,我们写入:self = super initWithNibName:nibNameOrNil bundle:nibBundleOrNil;if (self) self setWords:” pleaseanswer the door”;很显然,我们通过覆盖 initWithNibName 方法,修改了从 superclass 继承来的 words 属性。如果我们想打印 pleaseanswer the door 这段文本,你可能会想重用 superclass 的viewDidLoad 方法:- (void)viewDidLoadsuper viewDidLoad; 好了,运行程序。在加载 superclass.xib 时,控制台将打印 somebodyis knocking。而加载subclass.xib 时,控制台会打印 please answer the door。Hey,等一等。为什么我会在两个 ViewController 中都看到了 somebody is knocking?不用看了,subclass 对象的 words 属性确实是 pleaseanswer the door。如果你正在调试代码,那么可以 debug 区中确认这一点。问题在于 subclass 的初始化出现了问题。看这一句:self=superinitWithNibName:nibNameOrNil bundle:nibBundleOrNil;这句代码将导致 IB 加载 nib 文件,并立即调用 viewDidLoad 方法。我们可以看到在初始化subclass 时的调用顺序如下:1. subclass-initWithNibName2. superclass-initWithNibName3. superclass-setWords4. subclass-viewDidLoad5. superclass-initWithNibName6. subclass-setProperty让我再解释一下:1. 首先 subclass 的 initWithNIbName 方法调用。2. 接着调用 superclass 的 initWithNibName 方法。3. 在 superclass 的 initWithNibName 方法中,words 属性被设置为 somebodyis knoking。4. superclass 的 initWithNibName 方法结束,表示 nib 文件已加载,则调用 nib 文件的 Filesowner 所指向的 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)viewDidLoadselfsetWords:” pleaseanswer the door”;super viewDidLoad; 结论由于 initWithNibName 或者是 IB 这些限制,.nib 文件违反了面向对象的原则。 .nib 文件无法从另一个.nib 文件继承。不管你的类如何继承,但 nib 文件中不会保存类的层次结构,Filesowner 也无法指向类链。initWithNibName 导致的初始化问题众所周知,IB 在加载 nib 的过程中存在着一些 undocument 行为,有的行为确实是不可理喻的,因此程序员对 IB 产生了抗拒心理。今天我们要介绍的是 IB 导致的一个奇特行为。通过本文的描述, 作者完美地展示了 IB 给面向对象所带来的破坏作用。我们有两个 View Controller,暂名为 superclass 和 subclass。subclass 继承了superclass。在 superclass 的 initWithNibName 初始化方法中,我们这样写道:self = super initWithNibName:nibNameOrNil bundle:nibBundleOrNil;if (self) self setWords:”somebody is knocking”;return self;在 superclass 的 viewDidLoad 方法中,我们这样写:super viewDidLoad;NSLog(get XXX:%, self words);然后我们用 subclass 继承 superclass。在 initWithNibName 方法中,我们写入:self = super initWithNibName:nibNameOrNil bundle:nibBundleOrNil;if (self) self setWords:” pleaseanswer the door”;很显然,我们通过覆盖 initWithNibName 方法,修改了从 superclass 继承来的 words 属性。如果我们想打印 pleaseanswer the door 这段文本,你可能会想重用 superclass 的viewDidLoad 方法:- (void)viewDidLoadsuper viewDidLoad; 好了,运行程序。在加载 superclass.xib 时,控制台将打印 somebodyis knocking。而加载subclass.xib 时,控制台会打印 please answer the door。Hey,等一等。为什么我会在两个 ViewController 中都看到了 somebody is knocking?不用看了,subclass 对象的 words 属性确实是 pleaseanswer the door。如果你正在调试代码,那么可以 debug 区中确认这一点。问题在于 subclass 的初始化出现了问题。看这一句:self=superinitWithNibName:nibNameOrNil bundle:nibBundleOrNil;这句代码将导致 IB 加载 nib 文件,并立即调用 viewDidLoad 方法。我们可以看到在初始化subclass 时的调用顺序如下:1. subclass-initWithNibName2. superclass-initWithNibName3. superclass-setWords4. subclass-viewDidLoad5. superclass-initWithNibName6. subclass-setProperty让我再解释一下:1. 首先 subclass 的 initWithNIbName 方法调用。2. 接着调用 superclass 的 initWithNibName 方法。3. 在 superclass 的 initWithNibName 方法中,words 属性被设置为 somebodyis knoking。4. superclass 的 initWithNibName 方法结束,表示 nib 文件已加载,则调用 nib 文件的 Filesowner 所指向的 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)viewDidLoadselfsetWords:” pleaseanswer the door”;super viewDidLoad; 结论由于 initWithNibName 或者是 IB 这些限制,.nib 文件违反了面向对象的原则。 .nib 文件无法从另一个.nib 文件继承。不管你的类如何继承,但 nib 文件中不会保存类的层次结构,Filesowner 也无法指向类链。
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号