我一直在尝试使用方便的初始值设定项覆盖 SKSpriteNode 初始值设定项,该初始值设定项允许我使用一些额外的属性实例化 SKSpriteNode 子项,但每次尝试时,我都会不断收到编译器错误。据我所知,这是两条大规则。
规则:
- 每个方便的初始值设定项都必须引用指定的初始值设定项,无论是来自类本身还是父类
- 必须在初始值设定项委托给父类之前设置子类属性。
这是我的代码,我相信它遵循规则:
class WalkingMonster: SKSpriteNode {
var rangeOfMovement: CGFloat
var originalPosition: CGFloat
var platformNumber: Int
var imageName = "walkingAlien"
var sizes = [CGSize(width: CGFloat(30.0), height: CGFloat(30.0)), CGSize(width: CGFloat(30.0), height: CGFloat(15.0)), CGSize(width: CGFloat(30.0), height: CGFloat(7.0))]
override init(texture: SKTexture?, color: UIColor, size: CGSize) {
super.init(texture: texture!, color: color, size: size)
}
convenience init(texture: SKTexture, color: UIColor, size: CGSize, rangeOfMovement: CGFloat, originalPosition: CGFloat, platformNumber: Int) {
self.rangeOfMovement = rangeOfMovement
self.originalPosition = originalPosition
self.platformNumber = platformNumber
self.init(texture: texture, color: color, size: size)
}
}
编译器告诉我要实现以下必需的 init,这只会抛出错误:
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
当我实现它时,我收到一个错误,说self.rangeOfMovement在super.init()调用时没有初始化,并且在调用self.init之前使用self委派初始化器。当我从初始值设定项中取出 self 时,它将每个成员变量视为函数的局部变量。
我尝试交换覆盖 init() 调用并在子类便利初始化器中使用 super.init()。
class WalkingMonster: SKSpriteNode {
var rangeOfMovement: CGFloat
var originalPosition: CGFloat
var platformNumber: Int
var imageName = "walkingAlien"
var sizes = [CGSize(width: CGFloat(30.0), height: CGFloat(30.0)), CGSize(width: CGFloat(30.0), height: CGFloat(15.0)), CGSize(width: CGFloat(30.0), height: CGFloat(7.0))]
convenience init(texture: SKTexture, color: UIColor, size: CGSize, rangeOfMovement: CGFloat, originalPosition: CGFloat, platformNumber: Int) {
self.rangeOfMovement = rangeOfMovement
self.originalPosition = originalPosition
self.platformNumber = platformNumber
super.init(texture: texture, color: color, size: size)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
我收到一个错误,说 WalkingMonster 的便利初始值设定项必须使用 self.init 委托,而不是使用 super.init() 链接到超类初始值设定项,我之前已经尝试过实现但没有成功。我觉得覆盖初始化属性应该是一件非常简单的事情,我一定错过了一些东西。一如既往,任何帮助,非常感谢
编译器是对的:除了你还没有初始化你的属性之外,你的覆盖会很好。如果需要参数来执行此操作,则需要创建一个新的指定初始值设定项:您的init(texture: SKTexture, color: UIColor, size: CGSize, rangeOfMovement: CGFloat, originalPosition: CGFloat, platformNumber: Int)
就可以了;只需从中删除convenience
,因为它是新指定的初始值设定项,而不是方便的初始值设定项。(正如编译器指出的那样,方便的初始值设定项必须委托给self.something
,而不是像您希望的那样向上。
至于init?(coder:)
,只要你永远不打算编码或解码子类的实例,就可以使用 fatalError
版本。如果你确实需要使用NSCoding
,那么你也需要提供一个init?(coder:)
的工作实现,并覆盖encodeWithCoder(_:)
。