讲道理 OC 的时候我就不喜欢使用 KVO,总感觉记不住这东西怎么用,每次用的时候都得去查一下。。。感觉很难用啊。但是 KVO 这个东西在 OC 这样一门动态语言下也是极其强大的,不容忽视,现在开始玩 Swift , 那怎么在 Swift 环境下使用 KVO 呢? 在 Swift 中我们也是可以使用 KVO 的,但是仅限于在 NSObject 的子类中。这是因为 KVO 是基于 KVC (Key-Value Coding) 以及动态派发技术实现的,而这些东西都是 Objective-C 运行时的概念。另外由于 Swift 为了效率,默认禁用了动态派发,因此想用 Swift 来实现 KVO,我们还需要做额外的工作,那就是将想要观测的对象标记为 dynamic。
来看实现代码:
import UIKit
class Person: NSObject {
// 想用 Swift 来实现 KVO,我们还需要做额外的工作,那就是将想要观测的对象标记为dynamic。。
var name = "青"
dynamic var age = 18
var sex = "女"
var height = 170
override init() {
super.init()
}
}
复制代码
上述代码定义了一个 Person 类,其实你也可以把它看成 Model。 其中 age 属性使用 dynamic 标记,这就意味着只能对 Person对象的 age 属性来进行监听,如果对其他属性进行监听的话,将不会有效果。
然后我们队 Person 对象添加观察者。
var person = Person()
override func viewDidLoad() {
super.viewDidLoad()
// 为 person添加观察者,观察 age 属性的值是否有了新的赋值。
person.addObserver(self, forKeyPath: "age", options: .new, context: nil)
}
复制代码
接下来我们改变 age 的值,看是否会触发监听:
@IBAction func click(_ sender: UIButton) {
person.age = 20
}
复制代码
调用观察者的方法:
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
// 输出改变后的新值
print(change![NSKeyValueChangeKey.newKey]!)
}
复制代码
最后别忘记移除观察者
override func viewWillDisappear(_ animated: Bool) {
person.removeObserver(self, forKeyPath: "age")
}
复制代码
参考文献: 喵神的文章 KVO 我写的是基本使用,喵神则分析的更深层,大家可以去看看 很有帮助的。