本文介绍了在 Swift 子类中添加便利构造器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为一个学习练习,我试图实现一个 SKShapeNode 的子类,它提供了一个新的便利初始化器,它接受一个数字并构造一个 ShapeNode,它是一个数字宽度和高度的平方.

As a learning exercise I am trying to implement a subclass of SKShapeNode that provides a new convenience initializer that takes a number and constructs a ShapeNode that is a square of number width and height.

根据Swift 书:

如果您的子类没有定义任何指定的初始化器,它会自动继承其所有超类指定的初始化器.

如果您的子类提供了其所有超类指定初始值设定项的实现——或者按照规则 1 继承它们,或者通过提供自定义实现作为其定义的一部分——那么它会自动继承所有超类便利初始值设定项."

If your subclass provides an implementation of all of its superclass designated initializers—either by inheriting them as per rule 1, or by providing a custom implementation as part of its definition—then it automatically inherits all of the superclass convenience initializers."

但是,以下类不起作用:

However, the following class doesn't work:

class MyShapeNode : SKShapeNode {
    convenience init(squareOfSize value: CGFloat) {
        self.init(rectOfSize: CGSizeMake(value, value))
    }
}

相反,我得到:

Playground execution failed: error: <REPL>:34:9: error: use of 'self' in delegating initializer before self.init is called
        self.init(rectOfSize: CGSizeMake(value, value))
    ^
<REPL>:34:14: error: use of 'self' in delegating initializer before self.init is called
    self.init(rectOfSize: CGSizeMake(value, value))
         ^
<REPL>:35:5: error: self.init isn't called on all paths in delegating initializer
}

我的理解是 MyShapeNode 应该继承 SKShapeNode 的所有便利初始化程序,因为我没有实现任何自己指定的初始化程序,并且因为我的便利初始化程序正在调用init(rectOfSize),另一个方便的初始化器,这应该可以工作.我做错了什么?

My understanding is that MyShapeNode should inherit all of SKShapeNode's convenience initializers because I am not implementing any of my own designated initializers, and because my convenience initializer is calling init(rectOfSize), another convenience initializer, this should work. What am I doing wrong?

推荐答案

我对 Initializer Inheritance 的理解和你的一样,而且我认为我们都与书中所说的一致.我不认为这是解释问题或对规定规则的误解.也就是说,我不认为你做错了什么.

My understanding of Initializer Inheritance is the same as yours, and I think we are both well aligned with what the book states. I don't think it's an interpretation issue or a misunderstanding of the stated rules. That said, I don't think you're doing anything wrong.

我在 Playground 中测试了以下内容,它按预期工作:

I tested the following in a Playground and it works as expected:

class RectShape: NSObject {
    var size = CGSize(width: 0, height: 0)
    convenience init(rectOfSize size: CGSize) {
        self.init()
        self.size = size
    }
}

class SquareShape: RectShape {
    convenience init(squareOfSize size: CGFloat) {
        self.init(rectOfSize: CGSize(width: size, height: size))
    }
}

RectShape 继承自 NSObject 并且没有定义任何指定的初始值设定项.因此,根据规则 1,它继承了所有 NSObject 的指定初始值设定项.在为实例进行设置之前,我在实现中提供的便利初始化器正确地委托给指定的初始化器.

RectShape inherits from NSObject and doesn't define any designated initializers. Thus, as per Rule 1, it inherits all of NSObject's designated initializers. The convenience initializer I provided in the implementation correctly delegates to a designated initializer, prior to doing the setup for the intance.

SquareShape 继承自 RectShape,不提供指定的初始值设定项,同样,按照规则 1,继承所有 SquareShape's 指定的初始值设定项.根据规则 2,它还继承了 RectShape 中定义的便利构造器.最后,SquareShape 中定义的便利构造器正确地委托给继承的便利构造器,后者又委托给继承的指定构造器.

SquareShape inherits from RectShape, doesn't provide a designated initializer and, again, as per Rule 1, inherits all of SquareShape's designated initializers. As per Rule 2, it also inherits the convenience initializer defined in RectShape. Finally, the convenience initializer defined in SquareShape properly delegates across to the inherited convenience initializer, which in turn delegates to the inherited designated initializer.

因此,鉴于您没有做错任何事情并且我的示例按预期工作,我推断出以下假设:

So, given the fact you're doing nothing wrong and that my example works as expected, I am extrapolating the following hypothesis:

由于SKShapeNode 是用Objective-C 编写的,每个便利构造器都必须从同一个类中调用另一个构造器"的规则并没有被语言强制执行.因此,也许 SKShapeNode 的便利初始化程序实际上并没有调用指定的初始化程序.因此,即使子类 MyShapeNode 按预期继承了便利构造器,它们也没有正确地委托给继承的指定构造器.

Since SKShapeNode is written in Objective-C, the rule which states that "every convenience initializer must call another initializer from the same class" is not enforced by the language. So, maybe the convenience initializer for SKShapeNode doesn't actually call a designated initializer. Hence, even though the subclass MyShapeNode inherits the convenience initializers as expected, they don't properly delegate to the inherited designated initializer.

但是,同样,这只是一个假设.我所能确认的是,机制在我自己创建的两个类上按预期工作.

But, again, it's only a hypothesis. All I can confirm is that the mechanics works as expected on the two classes I created myself.

这篇关于在 Swift 子类中添加便利构造器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 14:41