繁体   English   中英

初始化属性时未调用didSet观察器

[英]didSet observer does not get called when initialising property

鉴于以下课程,

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块中包含的同一行代码,还可以触发后者,但这似乎行不通。 当创建场景时(在主GameScene中,该场景仅创建一个Spaceship对象,并将spaceship.node添加到场景的子节点中),该node的位置似乎为0; 0 0; 0

为什么会发生这种情况的任何线索? 谢谢。

更新:尽管defer语句有效,但是赋值不允许使用它。

与其使用didSet更新节点, 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 }
    }
}

在调用超类初始化器之后,在子类初始化器中设置属性时,将调用超类属性的willSet和didSet观察器。 在类设置其自己的属性时 ,在调用超类初始化程序之前, 不会调用它们

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

我个人只是将Spaceship子类化为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)时,您将遇到问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM