KVO 是 Objective-C 对观察者模式的实现。当被观察对象的某个属性发生更改时,观察者对象会获得通知。
KVO实现依赖于Objective-C的Runtime,所以Swift需要使用@objc暴露api给Objective C。
Swift目前没有内置原生实现的值观察系统,Swift 4的KVO使用dynamic属性来实现。
被观察的类
class Person: NSObject {
let name: String
@objc dynamic var age: Int
}
Person类的age就KVO属性。被观察的类需要满足以下几点:
1、类需要继承与NSObject,非NSObject子类不支持KVO
2、被观察属性需要为dynamic属性
3、被观察的属性需要使用@objc声明,这是因为Swift 4不再自动给NSObject的子类添加@objec。如果整个类的属性都需要被观察,可以使用@objcMembers
注册观察
let person= Person(name: "Jack", age: 5)
let observation = person.observe(\.age) { (p, change) in
print("initial \(p.age)")
}
如果需要观察新旧值得变化,可以使用options
let observation = person.observe(\.age, options: [.initial, .old, .new, .prior]) { (p, change) in
print("initial \(p.age)")
print("old \(p.oldValue)")
print("new \(p.newValue)")
print("is p \(p.isPrior)")
}
这里使用Swift 4新增的Key Path语法:\.age,它是Person.age的简写方式。