`
啸笑天
  • 浏览: 3462415 次
  • 性别: Icon_minigender_1
  • 来自: China
社区版块
存档分类
最新评论

initWithNibName和viewDidLoad执行顺序

 
阅读更多

 

众所周知,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)viewDidLoad{
    [super viewDidLoad];  
}

好了,运行程序。在加载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测试

  • T1.zip (34.7 KB)
  • 下载次数: 11
分享到:
评论

相关推荐

    initWithCoder与initWithFrame

    每个ios开发者对loadView和viewDidLoad肯定都很熟悉,虽然这两个函数使用上真的是非常简单,但是和类似的initWithNibName/awakeFromNib/initWithCoder放在一起还是非常容易让人混淆的. 昨天看了下苹果官方的相关文档...

    Lua_wax在ios上的应用.pptx

    self.super:initWithNibName_bundle("MyControllerView.xib", nil) return self end function viewDidLoad() -- 这里执行其他视图加载操作 end ``` 然而,Wax在实际应用中也存在一些局限性。例如,Wax的`wax_...

    福昕软件招聘iOS开发工程师面试题

    1. UIViewController调用顺序:`initWithNibName:bundle:` -> `loadView` -> `viewDidLoad` -> 使用视图 -> `viewDidUnload` -> `dealloc`。`initWithNibName:bundle:`初始化,`loadView`加载视图,`viewDidLoad`...

    iOS开发教程之UIView和UIViewController的生命周期详解

    在上述代码中,我们重写了这些初始化方法来打印日志,以便观察各个方法的执行顺序。`awakeFromNib`方法在从XIB或Storyboard加载视图时被调用,而`layoutSubviews`则在视图需要布局时自动调用,例如在屏幕旋转或者父...

    视图控制对象的区别及使用

    5. `viewDidAppear:` 和 `viewDidDisappear:` 视图完全显示和完全消失后调用,可用于执行一些动画效果或清理工作。 在实际项目中,我们可能会遇到多个视图控制器协作的情况,比如通过导航控制器...

    iOS经验之初始化方法中不该设置self.view的属性浅析

    这可能导致未预期的代码执行顺序,比如数据源的赋值发生在`viewDidLoad`之前,从而导致数据无法正常显示。 因此,正确的做法是在`viewDidLoad`或更晚的生命周期方法中设置`self.view`的属性,如`viewWillAppear:`或...

    AutoLayoutFlowDemo:自动布局Autolayout约束调用顺序

    AutoLayoutFlowDemo AutoLayoutFlowDemo 这个Demo主要用来展示约束到布局生效的过程。 并不针对约束的使用说明,是...1. -initWithNibName 如果使用 StoryBoard 加载 ViewController ,则会直接调用 -initWithCoder

    iOS中的View Controller Lifecycle

    - `initWithNibName:bundle:`:当从故事板或 nib 文件加载View Controller时,此方法被调用,传入 nib 文件名和资源包。 - `awakeFromNib`:当 nib 文件加载完成后,此方法会被调用,此时View Controller的所有...

    cocoa常用类及方法

    `viewDidLoad`和`viewDidUnload`分别在视图加载完成和卸载后被调用,用于初始化和清理工作。`shouldAutorotateToInterfaceOrientation:`决定了控制器能否根据设备方向自动旋转界面。 `UIView`是所有可视控件的基类...

    iphone视图控制器例子

    3. **生命周期方法**:如`viewDidLoad`、`viewWillAppear`、`viewDidAppear`、`viewWillDisappear`和`viewDidDisappear`等,这些方法在视图控制器的生命周期中被调用,是添加额外逻辑的好时机。 4. **导航控制器** ...

    IOS应用源码——TabBarController(标签).zip

    4. **管理Tab的顺序和可见性** - 可以通过`viewControllers`属性获取或设置TabBarController的子视图控制器数组,通过调整数组顺序改变Tab的显示顺序。 - 若要隐藏某个Tab,可以将其从数组中移除,但需要注意不要...

    Cocoa常用类和方法

    初始化方法-(id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle用于加载指定的nib文件,nibName不包含扩展名,nibBundle指定了nib文件所在的资源包。当视图加载完成后,系统会调用-(void)...

    UIScrollView定时滚动和循环滚动,可点击图片和PageController

    `initWithNibName:bundle:`方法是初始化控制器的地方,这里主要进行自定义初始化,但在这个例子中并未有特别的定制。 `scrollToNextPage:`方法是用于定时滚动的核心,它根据当前页码和`UIScrollView`的大小计算出...

    斯坦福大学开放课程:iOS开发教程2010年秋(Lecture 7)

    - `(id)initWithNibName:(NSString*)nibName bundle:(NSBundle*)bundle;`:这是一个常见的初始化方法,可以在这里进行一些基本的初始化工作。 - `-(void)awakeFromNib`:这个方法会在从XIB文件加载完毕后调用,...

    联系人分组列表

    - 在`viewDidLoad`方法中初始化数据源和TableView。 3. **数据源方法**: - `numberOfSectionsInTableView:`:返回分组的数量。 - `tableView:numberOfRowsInSection:`:对于每个分组,如果该分组被展开,则返回...

    iOS自动生成表格效果的实现代码

    这篇教程将详细介绍如何在iOS中自动生成表格效果,适用于初学者和有一定经验的开发者,旨在提高开发效率并提供一种简洁的界面展示方式。 首先,我们要了解在iOS中实现表格效果通常有几种方法:使用UITableView、...

    UIViewController的加载方式和UIView的加载详解

    FirstViewController *first = [[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:nil]; ``` 需要注意的是,使用XIB文件时,应避免文件名与控制器类名相似,以免造成混淆和错误。 ### ...

    objective-c 程序设计 + 代码

    3. **构造方法(Init Methods)**:初始化方法如`-init`,`-initWithCoder:`和`-initWithNibName:bundle:`用于创建并设置新对象的状态。 4. **分类(Categories)**:使用`+load`和`+initialize`方法,可以在类加载...

Global site tag (gtag.js) - Google Analytics