Inline KVO of a Property in another view controlle

2019-03-02 11:10发布

问题:

I have a vc with a dynamic var "value" and i need to know when it's changed in a closure in the calling cv.

target vc:

@objc dynamic var value: String = ""

source:

if let vc: TagButtonPopupViewController = sb.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("TagPopupViewController")) as? TagButtonPopupViewController {
        // configure vc
        vc.value = sender.title

        // observe
        _ = vc.observe(\.value) { (tbvc, change) in
            print("new string")
        }

        // present popup
        presentViewController(vc, asPopoverRelativeTo: sender.bounds, of: sender, preferredEdge: NSRectEdge.maxY, behavior: NSPopover.Behavior.transient)
    }

but "observe" is never called. Any Ideas how to get notified in a closure whenever "value" has changed in Swift4?

回答1:

The observer is destroyed because there is no reference to it after the other view controller has been presented. You have to store it

observer = vc.observe(\.value) { ... }

where observer is a property of the calling view controller.

A self-contained command-line project example: This prints "new string" as expected:

class A: NSObject {
    @objc dynamic var value: String = ""
}

let a = A()
let observer = a.observe(\.value) { (_, _) in print("new string") } // (*)
a.value = "Hello world"

But nothing is printed if (*) is replaced by

_ = a.observe(\.value) { (_, _) in print("new string") }