在Swift中的NSObject子类的初始化程序中调用super.init()

在Swift中的NSObject子类的初始化程序中调用super.init()

问题描述:

我正在Swift中构建一个iOS应用,并在 Lister 苹果提供的示例项目.

I'm building an iOS app in Swift and drawing on the Lister sample project Apple provides.

Lister使用两个模型对象:List和ListItem.我发现,即使他们都是NSObject的子类,他们两个都不会在初始化器中调用 super.init().

Lister uses two model objects: List and ListItem. I found that both of them do not call super.init() in their initializers even though they subclass NSObject.

但是,在Lister的Objective-C版本中,两个模型对象(AAPLList和AAPLListItem)都调用 [super init] .

However, in the Objective-C version of Lister, both model objects (AAPLList and AAPLListItem) do call [super init].

快速编程语言明确指出:指定的初始化程序必须从其直接超类调用指定的初始化程序."(初始化中初始化程序链接的规则1)

The Swift Programming Language clearly states that "designated initializers must call a designated initializer from their immediate superclass." (Rule 1 of Initializer Chaining in Initialization)

这是怎么回事?为什么这是一个例外,并且如果您不应该始终在子类中总是调用super.init(),那么将应用哪些规则?

What's going on here? Why is this an exception and if you shouldn't always call super.init() in a subclass, what rules do apply?

即使我在文档中找不到描述的地方,但发生的是在子类末尾调用了默认的超类初始化程序如果那是超类的唯一初始化器,并且没有被显式调用,则将其初始化.

Even though I can't find a place in the documentation where this is described, what happens is that the default superclass initialiser is called at the end of the subclass initialiser if that is the only initialiser of the superclass, and it wasn't called explicitly.

NSObject 仅具有默认的初始化程序(init()); ,您可以看到通过尝试引用self,在子类初始化程序的末尾调用了超类初始化程序(例如, println(self))在未调用 super.init()的构造函数中:那一点.

NSObject only has the default initialiser (init()); you can see that the superclass initialiser is called at the end of the subclass initialiser by attempting to reference self (eg. println(self)) in a constructor that does not call super.init(): You are not allowed to do it because the class is not fully initialised at that point.

如果要在构造函数中的某处使用self,则需要在此时完全构建对象,因此需要在此之前手动调用 super.init().

If you want to use self somewhere in the constructor, the object needs to be fully constructed at that point, so you need to call super.init() manually before then.