• initWithNibName和viewDidLoad执行顺序


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

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

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

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

    在superclass的initWithNibName初始化方法中:

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

    在superclass的viewDidLoad方法中:

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

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

    Java代码  收藏代码
    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方法:

    Java代码  收藏代码
    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测试

  • 相关阅读:
    每秒处理请求数和并发的关系
    oracle查看表空间及大小
    Oracle 备份还原
    ABOUT BENJAMIN HARDY, PHD
    ServiceActivationException when auto-starting WCF services with AutofacServiceHostFactory
    Welcome Enterprise Skills Initiative
    How to quickly delete all html objects in Excel?
    How does SQLParameter prevent SQL Injection?
    Is it necessary to add a @ in front of an SqlParameter name?
    VS Code Python 全新发布
  • 原文地址:https://www.cnblogs.com/wangpei/p/3549729.html
Copyright © 2020-2023  润新知