注:文章参考链接https://www.cnblogs.com/luobenpaidui/p/9354410.html,在此表示感谢。。。
在swift4.0 中 KVO 出现了变更,添加了监听回调.变得更加简单易用.同时会自动释放.不用再remove了.但是相对于OC中使用来说还是有一些需要注意的地方:
- 被监听的类需要用 @objcMembers 修饰,否则无法触发
- 你需要监听哪个属性,则该属性需要用dynamic 修饰,否则不会触发回调
实现方式一
@objcMembers class MyNumber: NSObject {
dynamic var value : Int = 1
}
class ViewController: UIViewController {
var testNum : MyNumber!
override func viewDidLoad() {
super.viewDidLoad()
testNum = MyNumber.init()
testNum.addObserver(self, forKeyPath: "value", options: [.new, .old], context: nil)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
testNum.value += testNum.value
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if let old = change?[.oldKey] {
print(old)
}
if let new = change?[.newKey] {
print(new)
}
}
deinit {
testNum.removeObserver(self, forKeyPath: "value", context: nil)
}
}
实现方式二
@objcMembers class MyNumber: NSObject {
dynamic var value : Int = 1
}
class ViewController: UIViewController {
var testNum : MyNumber!
//需要添加一个属性来持有NSKeyValueObservation 否则在函数执行完毕后将会被释放
var observer : NSKeyValueObservation?
override func viewDidLoad() {
super.viewDidLoad()
testNum = MyNumber.init()
observer = testNum.observe(\MyNumber.value, options: [.old, .new]) { (model, change) in
if let old = change.oldValue {
print(old)
}
if let new = change.newValue {
print(new)
}
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
testNum.value += testNum.value
}
deinit {
testNum.removeObserver(self, forKeyPath: "value", context: nil)
}
}
实现方式三——使用RxSwift
@objcMembers class MyNumber: NSObject {
dynamic var value : Int = 1
}
class ViewController: UIViewController {
var testNum : MyNumber!
var observer : NSKeyValueObservation?
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
testNum = MyNumber.init()
testNum.rx.observeWeakly(Int.self, "value")
.subscribe(onNext: { (value) in
print(value as Any)
}).disposed(by: disposeBag)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
testNum.value += testNum.value
}
}