为什么一个SKSpriteNode的子类在没有使用encode(with:)方法的情况下也能正常工作

3

NSCoding协议规定:

任何需要进行编码的对象类都必须采用NSCoding协议并实现其方法。

两个必需的方法是init?(coder: NSCoder)func encode(with: NSCoder)

SKSpriteNode继承自SKNode,后者符合该协议。当编写一个新的SKSpriteNode子类时,Xcode的自动完成会建议使用以下代码以满足NSCoding协议要求:

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

调用super也可以起作用:
required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

为什么这段代码在没有实现encode(with: NSCoder)的情况下也能够满足NSCoding的要求?

对我来说,只有在我开始编写子类时,例如 class MySprite: SKSpriteNode { init() },自动完成消息才会被触发。 - peacetype
1个回答

3

如果你在子类中编写自己的指定初始化器,但不是encode方法,Xcode只会告诉你添加所需的初始化器,对吗?这是因为实际上,NSCoding的要求已经在超类SKSpriteNode中实现。这就是你不需要实现encode的原因。它已经被继承了。

然而,初始化程序是不同的。您只能在遵循以下规则的情况下从父类继承初始化程序:

规则 1

如果您的子类没有定义任何指定的初始化程序,则自动继承其超类的所有指定的初始化程序。

规则 2

如果您的子类提供了其超类指定初始化器的所有实现-通过规则1继承它们或作为其定义的一部分提供自定义实现-则它自动继承了所有超类便利初始化程序。

看一下规则1!只有在你自己没有指定初始化器的情况下,才会继承指定的初始化器!因此,通过添加以下内容:

init() {}

你正在为你的类添加指定初始化方法,这会阻止该类自动继承超类的初始化方法。这就是为什么你需要添加一个"required init"的原因。

啊,谢谢……我突然恍然大悟了。有时候不能看到苹果的类是如何实现的真是令人沮丧。但是我想既然Swift现在是开源的,我们可以看一看它的实现方式。 - peacetype

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接