检查 change 是否是 initial 类型的 key value observing swift 3

check if change is of type initial in key value observing swift 3

覆盖observeValue键值观察时,可以通过change?[.newKey]或change?[.oldKey]查看变化是新的还是旧的。但是我如何检查是否没有变化但是变化只是第一次添加观察者时的初始值

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?)
{
    let newchange = change?[.newKey]
    let oldchange = change?[.oldKey]
}

来自documentation

The change dictionary in the notification will always contain an new​Key entry if new is also specified but will never contain an old​Key entry. (In an initial notification the current value of the observed property may be old, but it's new to the observer.)

所以,如果你想知道一个特定的变化是否是初始值,在添加观察者时请求.new.old,如果没有.oldKey在更改字典中,这意味着这是初始值。

这里有一些快速的 playground 代码来演示:

import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

@objc class Test: NSObject {
    var blah: String? = "Test" {
        willSet {
            self.willChangeValue(forKey: "blah")
        }
        didSet {
            self.didChangeValue(forKey: "blah")
        }
    }
}

var test = Test()

@objc class Observer: NSObject {
    func blah() {
        test.addObserver(self, forKeyPath: "blah", options: [.initial, .new, .old], context: nil)
    }

    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {

        if let change = change {
            print(change)
        }
    }
}

var observer = Observer()

observer.blah()

test.blah = "Test2"
test.blah = nil

这是输出:

[__C.NSKeyValueChangeKey(_rawValue: new): Test, __C.NSKeyValueChangeKey(_rawValue: kind): 1]
[__C.NSKeyValueChangeKey(_rawValue: new): Test2, __C.NSKeyValueChangeKey(_rawValue: kind): 1, __C.NSKeyValueChangeKey(_rawValue: old): Test]
[__C.NSKeyValueChangeKey(_rawValue: new): <null>, __C.NSKeyValueChangeKey(_rawValue: kind): 1, __C.NSKeyValueChangeKey(_rawValue: old): Test2]