Richard Topchii
Richard Topchii

Reputation: 8185

KVO Swift: newValue is always nil

Having the following example:

import UIKit

@objc class ViewController: UIViewController {

    @objc dynamic var buggyApple: NSObject?

    var obs: NSKeyValueObservation?

    override func viewDidLoad() {
        super.viewDidLoad()
        obs = observe(\.buggyApple, changeHandler: { (obj, change) in
            print(change)
        })
        buggyApple = NSObject()
        buggyApple = NSObject()
    }
}

I get the corresponding output in the debug console:

NSKeyValueObservedChange<Optional<NSObject>>(kind: __C.NSKeyValueChange, newValue: Optional(nil), oldValue: Optional(nil), indexes: nil, isPrior: false)
NSKeyValueObservedChange<Optional<NSObject>>(kind: __C.NSKeyValueChange, newValue: Optional(nil), oldValue: Optional(nil), indexes: nil, isPrior: false)

While inspecting the ViewController object on breakpoint inside the callback in the LLDB, I get the following:

(lldb) po obj.buggyApple
▿ Optional<NSObject>
  - some : <NSObject: 0x600000908fa0>

So, in fact, the new NSObject has been successfully sent, however, the change is still references nil. Is there any problem in my code and how to fix it?

Upvotes: 4

Views: 1930

Answers (1)

David Pasztor
David Pasztor

Reputation: 54745

You need to supply the new option to the options input argument of the observer method to receive the new value in change.

obs = observe(\.buggyApple, options: [.new], changeHandler: { (obj, change) in
    print(change)
})

Upvotes: 14

Related Questions