初始化属性时,didset观察者不会被调用



给定以下类,

class Spaceship {
    var position: CGPoint! {
        didSet {
            node.position = position
        }
    }
    var node: SKSpriteNode!
    init(frame: CGRect) {
        node = SKSpriteNode(
            color: UIColor.red,
            size: CGSize(
                width: frame.size.width / 5,
                height: frame.size.width / 5
            )
        )
        self.position = CGPoint(x: frame.midX, y: frame.midY)
    } 
}

看来position属性的didSet观察者没有被调用。

由于didSet观察者应在修改position属性时设置SpriteKit节点的位置,因此我认为我不使用didSet块中包含的相同代码,而是可以触发后者,但似乎并不是上班;当创建场景时(在主要的GamesScene中,仅创建Spaceship对象并将spaceship.node添加到场景的节点子女)时,node的位置似乎是0; 0

关于为什么会发生的任何线索?谢谢。

更新:尽管defer语句有效,但分配不允许使用它。

而不是使用 didSet更新您的节点,直接将查询转发到它:

class Spaceship {
    let node: SKSpriteNode
    init(frame: CGRect) {
        self.node = SKSpriteNode(
            color: UIColor.red,
            size: CGSize(
                width: frame.size.width / 5,
                height: frame.size.width / 5
            )
        )
        self.position = CGPoint(x: frame.midX, y: frame.midY)
    }
    var position: CGPoint {
        get { return node.position }
        set { node.position = newValue }
    }
}

在调用超类初始化器之后,当属性设置为子类初始化器中时,将调用超类属性的材料和DIDSET观察者。在称为SuperClass Initializer之前,当类别设置自己的属性时,他们没有被调用。

一种可能的解决方案可能是将position属性设置在Spaceship的初始化器之外,或者直接设置node的位置。

我个人只会作为SKSpriteNode子类飞机。宇宙飞船似乎不是一个复杂的对象,涉及继承上的组成。

class Spaceship : SKSpriteNode {
    convenience init(frame: CGRect) {
        self.init(
            color: UIColor.red,
            size: CGSize(
                width: frame.size.width / 5, 
                height: frame.size.width / 5
            )
        )
        self.position = CGPoint(x: frame.midX, y: frame.midY)
   } 
}

现在,我不确定您为什么要在这样的框架中传递。...我假设框架是您的场景?如果是这种情况,当锚点不是(0,0)时,您将遇到问题。

最新更新