4

我读到在init方法中使用属性被认为是不好的做法。但是我应该使用父类属性吗?

例如

-(id) init
{
    if (self = [super init])
    {
        self.parentProp = someVal; // (1)
        parentProp = someVal; // (2)
    }

    return self;
}

什么是首选(1 或 2),为什么?谢谢!

4

2 回答 2

3

在你调用了 super 的 init 方法并且它返回之后,你的对象的超类部分被初始化并准备好使用。在那之后您使用它的属性访问器是正常的,并且期望您使用它。例如。如果您创建了 的子类,那么在您的 init 方法中UIViewController设置您的(继承的)title 属性或修改您的 , 是正常的。navigationItem

也就是说,你可以打破这种行为。如果您重写了超类的方法之一(包括它的访问器方法之一),然后在 init 方法中调用该方法,则由您来确保在您的对象完全初始化之前您的重写方法将正常运行。

更微妙的是,也许你重写了一个超类方法,然后你调用了一个你没有重写的不同的超类方法。那么,如果你调用的方法转过来调用你已经覆盖的方法呢?您也需要意识到这种可能性。

综上所述,我重申,在通过调用其 init 方法之一对其进行初始化后,使用超类的属性访问器对其进行自定义是完全正常的。

于 2012-07-12T21:12:19.130 回答
1

回答你的问题 - 他们都没有。

  1. (2) 不是属性访问,而是直接实例变量访问。这取决于类层次结构设计,但总的来说,我强烈反对在非私有接口中使用 ivars - 有关详细信息,请参阅相关问题的答案
  2. 通常,您不应该在类初始化程序(以及在 dealloc 中)中使用任何类公共方法(包括属性访问) - 如果您的类层次结构不明确禁止子类化。因为如果你这样做 - 覆盖这些方法(或属性访问器)的子类将在处于无效状态(尚未初始化或已解除分配)时调用它们。

虽然我遇到了很多由 pt.2 引起的问题,但忽略它似乎是一种常见的做法(即在初始化程序中使用自身/父类属性)。所以我会说这取决于你。要么为你的类初始化器之外的显式设置编写更多代码,并且确信你永远不会遇到这个问题。或者可能有更简单/更短的初始化和更容易使用你的类,但要注意这个问题。

于 2012-07-12T19:07:35.323 回答