【问题标题】:Must an Objective-C class have exactly one designated initializer?Objective-C 类必须有一个指定的初始化器吗?
【发布时间】:2013-02-22 20:57:15
【问题描述】:

我在这个Apple's docs中找到了指定初始化器的一些信息,但我不明白的是,每个类必须只有一个指定初始化器?

例如,如果class A 具有initL, initM, initN,而class B 继承自class A 并具有initX, initY, initZ,该怎么办。有没有规定不能让initX 调用[super initL],initY 调用[super initM],initZ 调用[super initN]?

也就是说,不是所有的“辅助初始化器”都调用指定初始化器,然后每个指定初始化器都会调用[super initFoo],其中initFoo是超类的指定初始化器,我们不能只有3个主初始化器吗?每个调用者对应的超类的 3 个主初始化器? (也就是说,这些都继承自NSObject,只需调用self = [super init]。)

【问题讨论】:

    标签: objective-c initializer designated-initializer


    【解决方案1】:

    不,一个 obj-c 类可能有多个指定的初始值设定项。最常见的例子是-initWithCoder: 与-init。前者用于取消归档对象,后者用于所有其他初始化。

    也就是说,在-initWithCoder: 之外只有一个指定的初始化程序通常是一种很好的做法。这有助于防止代码重复,并且如果要为所有初始化调用子类,则必须重写哪个方法很明显。但是,如果您有很好的理由需要 3 个不同的指定初始化程序,那么没有什么可以阻止您这样做。请务必正确记录。

    【讨论】:

    • NSCell 甚至有 4 个指定的初始化器,根据 docs:init、initWithCoder:、initTextCell: 和 initImageCell:。
    • @Monolo: initTextCell: 和initImageCell: 大概是调用[self init]
    • 同意,但文档明确将它们列为指定的初始值设定项。不过,我一直想知道这是否是文档中的错误。
    【解决方案2】:

    指定初始化器是一个有助于防止递归调用并省略重要的基类初始化的概念。可以不遵循指定的初始化规则,仍然构建一个工作类层次结构。

    事实上,Cocoa 中有一些模式与纯指定初始化不同:例如 NSCoding 需要使用 initWithCoder: 初始化对象,但您仍然可以使用其他初始化程序从代码中初始化对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-11
      • 2016-05-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多