为SKSpriteNode子类创建初始化程序

时间:2016-03-06 20:56:44

标签: ios swift sprite-kit

我一直试图用一个方便的初始化程序覆盖SKSpriteNode初始化程序,它允许我实例化一个具有一些额外属性的SKSpriteNode子程序,但每次尝试时,我都会遇到编译器错误。这是我理解的两大规则。

规则:

  1. 每个便利初始值设定项必须引用指定的初始值设定项,无论是来自类本身还是父类
  2. 必须在初始化程序委托给父级之前设置子类属性。
  3. 以下是我认为符合规则的代码:

    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 个答案:

答案 0 :(得分:2)

编译器是正确的:除非你没有初始化你的属性,否则你的覆盖会很好。如果您需要有参数来执行此操作,那么您需要创建一个新的指定的初始值设定项:您的init(texture: SKTexture, color: UIColor, size: CGSize, rangeOfMovement: CGFloat, originalPosition: CGFloat, platformNumber: Int)将执行此操作;只需从中删除convenience,因为它是新的指定初始化程序,而不是便捷初始化程序。 (正如编译器指出的那样,便捷初始化程序必须将委托给self.something,而不是 up ,如你所愿。

对于init?(coder:),只要您永远不会编码或解码子类的实例,就可以使用fatalError版本。如果您 需要使用NSCoding,那么您还需要提供init?(coder:)的有效实施并覆盖encodeWithCoder(_:)。< / p>