`
wangpengfei360
  • 浏览: 1059607 次
文章分类
社区版块
存档分类
最新评论

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)viewDidLoad{

[super 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->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也无法指向类链。


分享到:
评论

相关推荐

    initWithNibName和viewDidLoad执行顺序

    NULL 博文链接:https://justsee.iteye.com/blog/1626231

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

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

    initWithCoder与initWithFrame

    方法去调用NIB文件初始化自身,即使那没有使用nib文件也会调用这个函数(默认情况下init方法已经为你的做这件事情了),如果你调用这个方法,并传递的两个参数为空(nil),然后类会调用-loadView去读取一个名字和你...

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

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

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

    在要以模态显示的视图控制器的初始化程序中,使用已注册的ModalTransitionType配置模态转换样式。 #pragma mark - Constructor - (id)init { if (self = [super initWithNibName:@"PopupViewControlle

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

    1、在infterface中定义数组并在init方法中初始化 代码如下: NSMutableArray *addressBookTemp;   – (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {  addressBookTemp = ...

    弹出框的运用

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

    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的理解 - ...

    ios开发记录

    //设置数组容量为0,可变数组随便设置只是个初始化的值 _diJiArr=[[NSMutableArray alloc]initWithCapacity:0]; // CGAffineTransform a = {1,2,3,4,1,1}; //CGAffineTransformMakeRotation 方法的作用就是...

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

    initWithNibName:@"MVYMenuViewController" bundle:nil]; // Create your main content view controller MVYContentViewController *contentVC = [[MVYContentViewController alloc] initWithNibName:@...

    支持背景视图加模糊效果

    使用方法:弹出视图: SamplePopupViewController *samplePopupViewController = [[SamplePopupViewController alloc] initWithNibName:@"SamplePopupViewController" bundle:nil];[self presentPopupViewController...

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

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

    NightModel:iOS 夜间模式

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

    MFComposeViewController:简单的composeViewController

    可客制化 使用自动版面设计 使用简单 安装及使用方法: 1-您需要将MFComposeClasses文件夹导入到您的项目中 2-添加此行进行显示: MFComposeViewController * composeViewController = [[MFComposeViewController...

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

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

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

    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return...

    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 = ...

    AXViewControllerTransitioning

    AXViewControllerTransitioning 例子 要运行示例项目,请克隆存储库,然后首先从Example目录运行pod install 。 要求 安装 ... 要安装它,只需将以下行...- (instancetype)initWithNibName:(NSString *)nibNameOrNil bun

Global site tag (gtag.js) - Google Analytics