Ios 为SKSpriteNode子类创建初始值设定项

Ios 为SKSpriteNode子类创建初始值设定项,ios,swift,sprite-kit,Ios,Swift,Sprite Kit,我一直在尝试用一个方便的初始值设定项覆盖SKSpriteNode初始值设定项,该初始值设定项允许我用一些额外的属性实例化一个SKSpriteNode子级,但每次尝试时,我都会收到编译器错误。这是我理解的两大规则 规则: 每个方便的初始值设定项都必须引用指定的初始值设定项,无论它来自类本身还是父类 必须在初始值设定项委托给父类之前设置子类属性 这是我的代码,我相信它遵循规则: class WalkingMonster: SKSpriteNode { var rangeOfMovement:

我一直在尝试用一个方便的初始值设定项覆盖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)
        }
    }
    
    编译器告诉我实现以下只会抛出错误的必需初始化:

    required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
    当我实现它时,我得到一个错误,说self.rangeOfMovement没有在super.init()调用时初始化,并且在调用self.init之前使用self来委托初始值设定项。当我将self从初始值设定项中取出时,它将每个成员变量视为函数的局部变量

    我尝试过交换override 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()链接到超类初始值设定项,我以前已经尝试过实现它,但没有成功。我觉得覆盖初始化属性应该是一件非常简单的事情,我肯定遗漏了什么。一如既往,非常感谢您提供的任何帮助

    编译器是正确的:您的重写将很好,除非您尚未初始化属性。如果您需要有参数来完成此操作,那么您需要创建一个新的指定初始值设定项:your
    init(纹理:SKTexture,颜色:UIColor,大小:CGSize,移动范围:CGFloat,originalPosition:CGFloat,platformNumber:Int)
    即可;只需从中删除
    便利
    ,因为它是新指定的初始值设定项,而不是便利初始值设定项。(正如编译器指出的,方便的初始值设定项必须委托给
    self.something
    ,而不是您希望的那样。)


    至于
    init?(coder:)
    ,只要不打算对子类的实例进行编码或解码,就可以使用
    fatalError
    版本。如果确实需要使用
    NSCoding
    ,则需要提供
    init?(coder:)
    的工作实现,并覆盖
    encodeWithCoder(:)

    它仍然需要NSCoder初始值设定项。这样可以吗,或者它会用fatalError使我的游戏崩溃(“init(coder:)还没有实现”)?崩溃的实现很好,只要你不调用它。如果您曾经使用
    NSCoding
    对子类进行编码或解码,则将调用它。