- (id)init使用指定的初始化程序?

时间:2010-05-27 12:52:25

标签: iphone objective-c cocoa-touch

在过去,我一直使用method_1:但我最近注意到一些实例,其中人们称之为超类指定的初始化。它是否重要,只是好奇它是否更多关于风格或实质?

Method_1:

-(id)init {
    self = [super init];
    if(self) {
        //do things ...
    }
    return self;
}

Method_2:

-(id)init {
    [super initWithNibName:nil bundle:nil];
    // do things ...
    return self;
}

-(id)initWithNibName:(NSString *)nibName bundle:(NSString *)bundle {
    return [self init];
}
欢呼加里

3 个答案:

答案 0 :(得分:4)

只有少数情况?

关于Designated initialisers的Apple文档在子类化上有这个说法:

  

一般原则:类中指定的初始值设定项必须通过超级消息调用超类中的指定初始值设定项。

此外:

  

指定的初始化程序通过消息链接到super,而其他初始化方法通过消息链接到指定的初始化程序。

如果符合以下条件,您的方法2将是正确的:

  • -initWithNibName:bundle:是超类的指定初始化程序
  • -init是你班级的指定初始化者(你的例子有点奇怪,因为你故意扔掉了nib名称和包参数)
  • -init被正确编码,不会丢弃[super initWithNibName:bundle:]
  • 的返回值

在您的课程中,您必须涵盖所有超类初始化方法,以确保最终调用您指定的初始化程序。

答案 1 :(得分:0)

对于超类具有指定初始化程序的类的init方法,上述任何一个都没有任何意义

 - (id)initWithNibName:(NSString *)nibName bundle:(NSString *)bundle

你想做什么?

答案 2 :(得分:0)

指定初始化器的想法是类的所有其他初始化函数应该调用它(这仅由约定强制执行)。这很好,因为这意味着编写子类的人可以在初始化时添加额外的步骤,同时只覆盖单个初始化。使用此模式时,方法1应仅在init 指定的初始化程序时发生。确保这种情况发生的一种策略如下:

假设C继承自B并且指定的初始化程序为d_c和d_b。我们在C中覆盖d_b,使其简单地调用d_c。由于d_b由B的所有其他初始化程序调用,因此确保子类中存在的所有初始化程序都调用d_c。然后我们让所有新的初始化程序也调用d_c。 d_c在其超类B中调用d_b,然后将该调用进一步传递给链。

请注意,此策略与通常初始化类的方式相反。例如,带参数a:1 b:2的初始化程序可以处理b参数,然后调用另一个只能处理a参数的初始化程序。当参数ab的函数很简单时,指定的初始化程序在更复杂的情况下效果更好。