我一直试图用一个方便的初始化程序覆盖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()链接到超类初始化程序,我之前已经尝试过该程序没有成功 . 我觉得重写初始化属性应该是一件非常简单的事情,我必须遗漏一些东西 . 一如既往,任何帮助,非常感谢
1 回答
编译器是正确的:你的覆盖会很好,除非你需要创建一个新的指定初始化器:你的
init(texture: SKTexture, color: UIColor, size: CGSize, rangeOfMovement: CGFloat, originalPosition: CGFloat, platformNumber: Int)
会做;只需从中删除convenience
,因为它是一个新的指定初始化程序,而不是一个便利初始化程序 . (方便初始化程序,正如编译器指出的那样,必须委托self.something
,而不是按照您的意愿进行 . )对于
init?(coder:)
,只要您永远不会编码或解码子类的实例,就可以使用fatalError
版本 . 如果您确实需要使用NSCoding
,那么您还需要提供init?(coder:)
的工作实现并覆盖encodeWithCoder(_:)
.