swiftcocoakey-value-observingnstoolbar

Key-Value-Observing closure never called on Boolean property


I have a class ToolbarManager that inherits from NSObject. It has a toolbar property defined as follows:

@objc dynamic let toolbar: NSToolbar

In the initializer of my class, I call the following code:

init(toolbar: NSToolbar) {
    self.toolbar = toolbar
    toolbar.allowsUserCustomization = true
    observation = observe(\.toolbar.customizationPaletteIsRunning, options: [.old, .new]) {
        (_, change) in
        print("was running: \(change.oldValue)")
        print("is running: \(change.newValue)")
    }
}

where observation is another property defined as follows:

var observation: NSKeyValueObservation?

When I run the app and select Customize Toolbar... or close the customization view, the observation closure is never called, and thus nothing is printed to the console.

Why?

(And how can I fix that?)


Edit:

The Apple documentation states:

You can only use key-value observing with classes that inherit from NSObject.

I'm not sure how to understand this. Does it mean that any property defined on NSObject subclasses can be observed or does it mean that only properties that are NSObject subclasses can be tracked?

(The latter would explain why my code doesn't work but then this example which observes a plain Swift string wouldn't work either. And it does work.)


Solution

  • You can only use key-value observing with classes that inherit from NSObject.

    means it's required that only objects in a subclass of NSObject can be observed.

    It does not mean that any object in a subclass of NSObject is implicitly observable.

    It seems that this property of NSToolbar is not KVO compliant.