KVO Swift:newValue 始终为零

Ric*_*hiy 2 objective-c-runtime key-value-observing swift

有以下例子:

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()
    }
}
Run Code Online (Sandbox Code Playgroud)

我在调试控制台中得到相应的输出:

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)
Run Code Online (Sandbox Code Playgroud)

ViewController在 中的回调内检查断点上的对象时LLDB,我得到以下信息:

(lldb) po obj.buggyApple
? Optional<NSObject>
  - some : <NSObject: 0x600000908fa0>
Run Code Online (Sandbox Code Playgroud)

所以,实际上 newNSObject已经成功发送了,但是,change仍然是引用nil。我的代码是否有问题以及如何解决?

Dáv*_*tor 10

您需要为方法newoptions输入参数提供选项observer以接收 中的新值change

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

  • 值得注意的是,Apple 建议不要使用“.new”,而只是从观察到的对象中读取当前值。 (2认同)
  • @RichardTopchiy 来自 Foundation 标头:“///newValue 和 oldValue 仅当 .new/.old 传递给 `observe()` 时才为非零。一般来说,通过直接访问来获取最新值而是观察到的物体。” (2认同)