• 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测试

  • 相关阅读:
    Windows Azure Cloud Service (14) 使用Windows Azure诊断收集日志记录数据
    Windows Azure Cloud Service (13) 用Visual Studio 2010 将应用程序部署到Windows Azure平台
    Windows Azure Cloud Service (15) 多个VM Instance场景下如何处理ASP.NET Session
    Windows Azure Storage (5) Windows Azure Drive
    Windows Azure Storage (7) 使用工具管理Windows Azure Storage
    SQL Azure(二) SQL Azure vs SQL Server
    webbrowser的自动提交
    提取视频的背景声音的软件
    Listview列排序的bug原因
    两个奇怪的问题
  • 原文地址:https://www.cnblogs.com/wangpei/p/3549729.html
Copyright © 2020-2023  润新知