一.概述
KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知。简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应的观察者了。
二.使用的步骤
1.注册,指定被观察者和观察的对象
objectToObserve.addObserver(self, forKeyPath: "contentArray", options: .new, context: &myContext)
2.实现属性变化的回调
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if context == &myContext {
} else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
}
3.移除观察
deinit {
objectToObserve.removeObserver(self, forKeyPath: "contentArray", context: &myContext)
}
三.完整的代码
@objcMembers class MyObjectToObserve: NSObject {
dynamic var contentArray = [String]()
}
private var myContext = 0
class PlaySpeechString: NSObject,AVSpeechSynthesizerDelegate {
static let shared = PlaySpeechString()
var objectToObserve = MyObjectToObserve()
// Make sure the class has only one instance
// Should not init or copy outside
private override init() {
super.init()
objectToObserve.addObserver(self, forKeyPath: "contentArray", options: .new, context: &myContext)
}
override func copy() -> Any {
return self // SingletonClass.shared
}
override func mutableCopy() -> Any {
return self // SingletonClass.shared
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if context == &myContext {
} else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
}
deinit {
objectToObserve.removeObserver(self, forKeyPath: "contentArray", context: &myContext)
}
}
注意:
1.被观察属性所在的类需要用 @objcMembers 关键字修饰 要不会报error
fatal error: Could not extract a String from KeyPath
Swift.ReferenceWritableKeyPath
2.被观察的属性需要用dynamic修饰,否则也无法观察到。