首页 文章

为SKSpriteNode子类创建初始化程序

提问于
浏览
2

我一直试图用一个方便的初始化程序覆盖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 回答

  • 2

    编译器是正确的:你的覆盖会很好,除非你需要创建一个新的指定初始化器:你的 init(texture: SKTexture, color: UIColor, size: CGSize, rangeOfMovement: CGFloat, originalPosition: CGFloat, platformNumber: Int) 会做;只需从中删除 convenience ,因为它是一个新的指定初始化程序,而不是一个便利初始化程序 . (方便初始化程序,正如编译器指出的那样,必须委托 self.something ,而不是按照您的意愿进行 . )

    对于 init?(coder:) ,只要您永远不会编码或解码子类的实例,就可以使用 fatalError 版本 . 如果您确实需要使用 NSCoding ,那么您还需要提供 init?(coder:) 的工作实现并覆盖 encodeWithCoder(_:) .

相关问题