【问题标题】:Objective-c using parent properties in init methodObjective-c在init方法中使用父属性
【发布时间】:2012-07-12 18:04:12
【问题描述】:

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

例如

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

    return self;
}

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

【问题讨论】:

    标签: objective-c inheritance properties


    【解决方案1】:

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

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

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

    话虽如此,我重申,在调用超类的 init 方法之一对其进行初始化后,使用超类的属性访问器对其进行自定义是完全正常的。

    【讨论】:

    • 所以我可以期待我的类在 init 方法中的完整多态行为? (我问是因为我最熟悉的语言是c++,如果从构造函数调用虚函数你会遇到问题)
    • 是的,你总是得到一个方法的最衍生版本,除非你明确地向super发送消息。这与 C++ 中的对象构造完全不同(而且简单得多)。
    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-23
      • 2012-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多