`
啸笑天
  • 浏览: 3433308 次
  • 性别: 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放在一起还是非常容易让人混淆的. 昨天看了下苹果官方的相关文档...

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

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

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

    定时滚动和循环滚动,可点击图片和PageController #import "ASIFormDataRequest.h" #import "GWPublicClass.h" @interface ViewController () @end @implementation ViewController { UIScrollView * ...

    NightModel:iOS 夜间模式

    NightModel iOS 夜间模式 夜间模式主要通过 NSNotificationCenter实现, 难点在于可扩展性 与 后期的维护性 ... 不能在 viewDidLoad方法中进行alloc init, 需要将alloc init放到 initWithNibName 中.

    iOS最佳实践:iOS软件设计最佳实践

    这样做几乎总是会导致难以调试的错误,因为在发出内存警告后,初始化逻辑将不会再次执行。 考虑一个简单的例子: - ( id )initWithNibName:( NSString *)nibNameOrNil bundle:( NSBundle *)nibBundleOrNil { if ...

    弹出框的运用

    PoPoverViewController * popover = [[[PoPoverViewController alloc]initWithNibName:@"PoPoverViewController" bundle:nil] autorelease]; popover.mainViewController = self; UIPopoverController * pcr = [...

    ios开发记录

    //initWithNibName将控制器绑定xib的方法,如果xib的名称和控制器的类名称相同的时候,直接写init(会自动绑定同名的xib)就可以,如果xib的名称和类名称不同的话,必须手动调用此方法来进行绑定 ...

    UINavigationController的最简单例子

    [[ViewController alloc]init]与[ViewController alloc]initWithNibName: bundle: ]的区别 - http://blog.csdn.net/moon_prince2013/article/details/49079173 对UIBackBarButtonItem的理解 - ...

    UINavigationController极简单的例子

    [[ViewController alloc]init]与[ViewController alloc]initWithNibName: bundle: ]的区别 - http://blog.csdn.net/moon_prince2013/article/details/49079173 对UIBackBarButtonItem的理解 - ...

    支持背景视图加模糊效果

    支持背景视图加模糊效果源码,该效果现在可以适配iOS7的弹出视图效果,而且还可以设置给背景视图加上模糊效果,和阴暗效果等,大家可以研究一下吧。使用方法:弹出视图: SamplePopupViewController *...

    一款实现弹出侧边菜单效果

    这是一款实现弹出侧边菜单效果,实现在弹出侧边菜单后,然后主视图会变小...打开菜单和关闭菜单: // Close menu animated [sideMenuController closeMenu]; // Open menu animated [sideMenuController openMenu];

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

    iOS初始化方法包括系统默认的和自定义的,常见系统初始化方法有init, initWithFrame:, initWithNibName:bundle:等,自定义则是各式各样。日常iOS项目开发过程中,我们经常在类的初始化方法中初始化接下来类需要用到...

    CCModalTransition:使用UIViewControllerAnimatedTransitioning API可扩展且易于使用的模式转换

    CCModalTransition 使用UIViewControllerAnimatedTransitioning API可扩展且易于使用的模式转换 ##安装 有两种在项目中使用库的方法: ... if (self = [super initWithNibName:@"PopupViewControlle

    JRCamera:本工程演示iOS相机的基本功能:拍照和录像。支持切换摄像头

    JRCamera 如何使用 ...JRCameraViewController *cameraVC = [[JRCameraViewController alloc] initWithNibName:@"JRCameraViewController" bundle:nil]; 2.presentViewController或用导航push都可以。

    iOS开发中使app获取本机通讯录的实现代码实例

    一、在工程中添加AddressBook.framework和AddressBookUI.framework 二、获取通讯录 1、在infterface中定义数组并在init方法中初始化 代码如下: NSMutableArray *addressBookTemp;   – (id)initWithNibName:...

    用户指引界面功能效果

    self.viewController = [[ICETutorialController alloc] initWithNibName:@"ICETutorialController_iPhone" bundle:nil andPages:tutorialLayers]; // Set the common styles, and start scrolling (auto ...

    ios开发小技巧

    nextWebView = [[WEBViewController alloc] initWithNibName:@"WEBViewController" bundle:nil]; [self presentModalViewController:nextWebView animated:YES]; //创建一个UIBarButtonItem右边按钮 ...

    IOS图片的原生(Graphics)详解及实例

    IOS图片的原生(Graphics)详解及实例 一,效果图。 二,工程图。 三,代码。 RootViewController.h #import @interface RootViewController : UIViewController ...- (id)initWithNibName:(NSSt

    PopupViewController:弹出视图控制器意味着覆盖容器

    弹出视图控制器用法 PopupViewController * _popViewController = [[PopupViewController alloc] initWithNibName:@"PopupViewController" bundle:[NSBundle mainBundle]]; _popViewController.alertType = ...

Global site tag (gtag.js) - Google Analytics