2

So there's this class in SpriteKit:

open class SKNode : UIResponder, NSCopying, NSCoding, UIFocusItem {

    ...

    open var scene: SKScene? { get }

    ...

I would like to trigger some logic when the scene property becomes not nil.

This is what I tried:

class MyNode : SKNode {

    override var scene: SKScene? {
        didSet {
            if scene != nil {
                // my custom logic
            }
        }
    }
}

but I'm getting an error: Cannot observe read-only property 'scene'; it can't change which makes sense in theory.

In practice, the value of the property does change:

let node = SKNode()
print(node.scene?)  // nil

scene.addChild(node)
print(node.scene?)  // SKScene

Is there some black magic that I could use instead?

scribu
  • 2,958
  • 4
  • 34
  • 44

1 Answers1

4

The property is computed, the value changes but it is never set. It is calculated from other values.

Therefore it makes no sense to put a didSet there.

From Read-Only Computed Properties

A computed property with a getter but no setter is known as a read-only computed property. A read-only computed property always returns a value, and can be accessed through dot syntax, but cannot be set to a different value.

If we are speaking about SKNode.scene, it's probably just an accessor method to a private ivar _scene, or, it dynamically goes up the tree and returns the root.

Since it is an Obj-C class, you can probably use KVO to observe the value, if you really really need it.

Sulthan
  • 128,090
  • 22
  • 218
  • 270
  • Found this question on using KVO for computed properties: http://stackoverflow.com/questions/36555492/kvo-on-swifts-computed-properties – scribu Jan 21 '17 at 00:18
  • 2
    The same error shows for `private(set)` properties. – kelin Apr 03 '19 at 11:18