简体   繁体   English

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

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

Given the following class, 鉴于以下课程,

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)

    } 

}

it looks as though the didSet observer of the position property does not get called. 好像没有调用position属性的didSet观察器。

Since the didSet observer should set the SpriteKit node's position when the position property gets modified, I thought that instead of using the same line of code contained within the didSet block, I could trigger the latter instead, but it doesn't seem to work; 由于didSet观察者应该在position属性被修改时设置SpriteKit节点的位置,所以我认为与其使用在didSet块中包含的同一行代码,还可以触发后者,但这似乎行不通。 when the scene gets created (in the main GameScene, which simply creates a Spaceship objects and adds the spaceship.node to the scene's node children), the node 's position seems to be 0; 0 当创建场景时(在主GameScene中,该场景仅创建一个Spaceship对象,并将spaceship.node添加到场景的子节点中),该node的位置似乎为0; 0 0; 0 . 0; 0

Any clue on why does this happen? 为什么会发生这种情况的任何线索? Thank you. 谢谢。

Update: although the defer statement works, the assignment does not allow to make use of it. 更新:尽管defer语句有效,但是赋值不允许使用它。

Rather than using didSet to update your node, directly forward queries to it: 与其使用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 }
    }
}

The willSet and didSet observers of superclass properties are called when a property is set in a subclass initializer, after the superclass initializer has been called. 在调用超类初始化器之后,在子类初始化器中设置属性时,将调用超类属性的willSet和didSet观察器。 They are not called while a class is setting its own properties , before the superclass initializer has been called. 在类设置其自己的属性时 ,在调用超类初始化程序之前, 不会调用它们

One possible solution could be to set the position property outside of the Spaceship 's initialiser, or also set directly the node 's position. 一种可能的解决方案是将position属性设置在Spaceship的初始化程序之外,或者也直接设置node的位置。

I personally would just subclass Spaceship as an SKSpriteNode. 我个人只是将Spaceship子类化为SKSpriteNode。 Spaceship does not seem to be a complex object that involves composition over inheritance. 宇宙飞船似乎并不是一个复杂的对象,它涉及到继承之上的合成。

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)
   } 
}

Now I am not sure why you are passing in frame like this.... I am assuming frame is your scene? 现在我不确定为什么要像这样在帧中传递...。我假设帧是您的场景? If this is the case, you are going to come across issues when anchor point is not (0,0). 如果是这种情况,当锚点不是(0,0)时,您将遇到问题。

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

相关问题 Swift didSet 已调用但未更新 UILabel - iOS 属性观察器 - Swift didSet called but not updating UILabel - iOS Property observer 获取声明为协议的属性时didSet调用 - didSet called when getting a property declared as a protocol 当我设置该属性的属性时,为什么在属性上调用'didset'? - Why is 'didset' called on a property when I set the property of that property? 在扩展中的弱属性上添加 didSet 观察者 - Add didSet observer on a weak property in an extension 使用didSet属性观察器而不声明'oldValue' - Using didSet property observer without stating 'oldValue' 为什么'='赋值运算符在didSet属性观察器的if语句中不起作用? - Why does the '=' assignment operator not work in my if statement in my didSet property observer? 有没有办法在更改类中的属性时让didSet工作? - Is there a way to get didSet to work when changing a property in a class? struct didSet 何时被多个变异变量触发? - When does struct didSet get triggered with multiple mutating variables? 在设置x的属性时,将setSet / didSet调用容器的存储属性x - willSet/didSet called on a container's stored property x when setting a property of x Swift - 绑定更改未调用 didSet 属性 - Swift - didSet property not called from binding changes
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM