2012-09-24 79 views
3

可以做以下事情吗?非指定初始值设定项可以调用超级指定初始值设定项吗?

1)一个非指定的初始化器调用超类的指定初始化器
2)一个类的指定初始化器调用超类的非指定初始化器?

,或者必须流是:

一)指定的初始化必须调用父类的指定初始化
二)非指定初始化必须调用自己的类的指定初始化

如果(1)或( 2)被违反,会发生什么? (或者,如果我们必须始终遵循的(a)和(b),什么是它背后的原因是什么?)

回答

3
  • 1:号
  • 2:是的。
  • a:可争辩。
  • b:是的。

指定初始值设定项的一点是,它是知道如何正确设置手边对象的初始值设定项。该类中的所有其他初始化器都应调用指定的初始化器;如果他们不这样做,该对象可能无法正确初始化。

苹果的可可文档讨论how to handle multiple initializers,它包括以下内容:

的一类,它利用 初始化参数通常是指定的初始化完全互补的初始化。指定的子类的初始值设定项必须通过向super发送消息来调用其超类的指定 初始值设定项。

这有点含糊不清 - 它听起来像一个子类的指定初始值设定项必须调用其超类的指定初始值设定项。但我不认为这是真正的意图。这里真正的意义在于,指定初始化程序的责任是确保通过向super发送消息来正确初始化超类。如果你碰巧通过调用super的非指定初始值设定项来做到这一点,那么应该罚款,只要该初始值设定项最终导致指定的初始值设定项被调用。为此,我不认为(2)是一个问题。

进一步阅读我们:

便利性(或继发性)初始化,其中可以包括初始化,不调用超。

所以他们在这里说的是,指定初始化和任何其他初始化之间的一个重要区别是,指定初始化是发送初始化消息super唯一的一个。回到(1),如果你有一个叫做[super init]的“非指定”初始值设定项,那不是一个非指定的初始值设定项。您的方法通过向super发送初始化消息承担指定初始化程序的责任。这不是必然一个问题 - 请注意,UIView有两个指定的初始化程序 - 但它打破了惯例,所以你应该有一个很好的理由去做。

2

由于创建指定的初始化程序不是正式的,违反规则取决于您。

对于具有多个初始化器的类而言,常见做法是使指定初始化器接受最多参数的一种做法,并让所有其他初始化器调用它。只有指定的初始化程序才能调用超类的指定初始化程序,它遵循相同的规则。

如果其他人对你的类进行子类化并调用指定的初始化程序,他们确信所有实例变量都被正确初始化。如果你的班级没有遵循这些常规做法,你可以创建一个凌乱的班级,为自己开始,但更难以用于其他人。

-1

可以做以下事情吗?

1)非指定初始化调用父类的指定 初始化

它实际上必须来完成,因为没有办法,你作为一个子类实现者可以知道的是指定的父类里面是什么码初始化器并且自己实现它而不用伪装代码。你没有其他合理的方法来启动超类。

无论您是子类还是外部客户端,都必须调用指定的初始化程序。上面引用的文档不正确。

2)一类的指定初始化调用超类的 非指定的初始化?

如果超级提供了非指定的初始值设定项,并且实现了调用指定的初始值设定项,那么在调用父级的任何初始值设定项时绝对没有问题。

以前的答案会让你看起来似乎必须在自己的代码中基本实现所有的超类构造函数,而不需要代码。错误。这就是为什么存在超类初始化器,以便您可以安全地扩展它们而不需要代码。

+0

答案的第一部分是错误的:指定初始化程序的定义是它是所有其他初始化程序必须调用的方法。如果d.i.是'-initWithRed:green:blue:',那么'-init'会调用'[self initWithRed:... green:... blue:...]'。 d.i.是您放置类所需的初始化代码的位置,其他初始化程序必须调用它才能执行该代码。 d.i.的职责是调用super的初始化程序之一。我不明白你的最后一段,但如果你指的是我的答案,或许你会足够好评论。 – Caleb

相关问题