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



我一直在尝试使用方便的初始值设定项覆盖 SKSpriteNode 初始值设定项,该初始值设定项允许我使用一些额外的属性实例化 SKSpriteNode 子项,但每次尝试时,我都会不断收到编译器错误。据我所知,这是两条大规则。

规则:

  1. 每个方便的初始值设定项都必须引用指定的初始值设定项,无论是来自类本身还是父类
  2. 必须在初始值设定项委托给父类之前设置子类属性。

这是我的代码,我相信它遵循规则:

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(_:)

最新更新