一同养成写作习气!这是我参加「日新计划 4 月更文应战」的第19天,点击查看活动详情。
- 本文首要介绍RxSwift中KVO的运用,和原理的剖析
1. Swift中KVO的运用
关于kvo在oc中咱们经过键值调查进行监测目标特点的改动,经过3步曲进行监听。
-
kvo相当于咱们实时监测某一个关怀的值,根据这个值的setter办法监听的,当调用这个值告知调查者,这个值要改动了,不必的时分移除调查。 -
kvo内部完成是经过一个
中心类去操作,中心类的setter首要是通知调查者值的改动,调用父类的setter办法,实践去改动。这样规划相当于一个中心类当成一个管家,外面只需叮咛一下,具体执行交给管家,降低了耦合性。 -
kvo
移除首要是还原isa,把实例目标的isa由中心类还原到本类,中心类不会毁掉,便利下次相关。
关于kvo的原理能够看下我之前的文章: kvo原理探究 那么关于swift怎样完成kvo呢?
1.1 方法1
相似咱们oc的方法,增加,调查,移除。
class Person: NSObject {
@objc dynamic var name:String = "jack"
}
var p = Person()
//增加
self.p.addObserver(self, forKeyPath: "name", options: .new, context: nil)
//呼应
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
print(change as Any)
}
deinit{
//移除
self.p.removeObserver(self, forKeyPath: "name", context: nil)
print("DetailViewController dealloc")
}
基本上来说swift仍是对oc的kvo进行封装,目标特点@objc dynamic修饰为了具有oc中的运行时才能
1.2 方法2
swift对kvo进行了封装便利咱们能够快发开发
@objc dynamic var p = Person()
self.kvo = observe(\.p.name, options: .new, changeHandler: { (_,change) in
print(change.newValue as Any)
})
这里咱们把整个目标当成一个运行时的目标,经过动态的拜访它的途径下,找到它发生改动的闭包回调然后到达监听的效果,同时不必咱们手动管理它的调查者。
2. RxSwift运用KVO
RxSwift对kvo也进行了封装,咱们运用也是比较简单
self.p.rx.observeWeakly(String.self, "name")
.subscribe(onNext: {print($0 as Any)})
.disposed(by: disposeBag)
咱们也能够运用observe
self.p.rx.observe(String.self, "name")
.subscribe(onNext: {print($0 as Any)})
.disposed(by: disposeBag)
打印结果
2.1 创立
observe创立

observe仅仅对kvo的简单的包装,生成一个KVOObservable的序列
能够调查咱们目标特点的途径,包含弱引证和强引证
途径必须只包含“强”特点,不然你可能会因为在dealloc之前没有刊出KVO调查者而导致系统崩溃

observeWeakly
关于observeWeakly咱们看下创立
它能够在一切能够运用“observe”的情况下运用,由于它不会保留被调查目标,因而能够用于调查一切权联系未知的任意目标图
它能够用来调查“弱引证”特点
2.1.1 KVOObservable
关于KVOObservable遵从了序列的协议因而能够订阅,其次遵从了KVOObservableProtocol,该协议界说了特点,然后让遵从的类能够拥有该协议的特点,避免了重新界说一个类或者继承的联系。
咱们持续看上面的初始化,首要关于target就是咱们调查的目标,在闭包中为了避免循环引证这里运用无主引证(比较弱引证,清晰了它的生命周期和持有者的一致性)retainTarget进行判读是否强持有
关于咱们observe是传的yes
关于咱们的observeWeakly进入observeWeaklyKeyPathFor办法
没有进行强持有。
持续咱们看KVOObservable的初始化里面的target为咱们要调查的目标,关于上面的Person,是面向目标。
2.1.2 observeWeakly 初始化流程
咱们看下observeWeakly的初始化
首要对keypath 进行处理之后 创立一个序列后调用finishWithNilWhenDealloc
当咱们调查的目标Person正在毁掉时分,发生一个空的序列,就不会引证person了。持续看下关于咱们调查目标person的特点是weak的时分是怎么处理的
经过获取调查目标的特点,进行判别没有特点的话则发生一个错误的序列,不然判别是否存在weak修饰的特点
之后持续创立一个KVOObservable的序列。
之后咱们的序列subscribe后调用这个序列的闭包,进行一些容错处理。
2.2 订阅
咱们创立了一个序列KVOObservable包含了咱们KVO的一些信息包含target,keypath等。咱们持续看下怎么订阅的和发送的
咱们看下序列自己完成的subscribe
创立咱们的调查者,callback的回调,发送信息
调查者继承_RXKVOObserver是oc类完成的,能够发现仍是完成了咱们三部曲
当咱们值发生改动的时分调用callback就会调外面的let observer = KVOObserver(parent: self) {}进行发送,判别咱们的value是否有值,发送on事件到的回调。
- dispose
关于咱们移除调查者能够发现在调用
dispose的时分会移除咱们调查者。
3. 总结
关于observeWeakly和observe运用场景基本上一样,仅仅observeWeakly会增加一些判别,比方目标是否在毁掉等,生成一些空的序列,或者错误序列。经过对kvo的封装发生一个中心者,进行发送序列,回调,毁掉。
















