RxSwift KVO的实现原理
RxSwift KVO的实现原理
RxSwift中的KVO使用是不需要自己移除观察者的,那它的底层实现原理是什么呢?
- 案例使用
person.rx.observe(String.self, "name").subscribe(onNext: { (change) in
print("observe订阅到了KVO:\(String(describing: change))")
}).disposed(by: disposeBag)
person.rx.observeWeakly(String.self, "name").subscribe(onNext: { (change) in
print("observeWeakly订阅到了KVO:\(String(describing: change))")
}).disposed(by: disposeBag)
- 源码流程分析图
- 源码分析
1、首先person.rx.observe(String.self, “name”)创建一个KVOObservable序列,这个序列中实现了KVOObservableProtocol协议,保存了target、keyPath等信息
public func observe<Element>(_ type: Element.Type, _ keyPath: String, options: KeyValueObservingOptions = [.new, .initial], retainSelf: Bool = true) -> Observable<Element?> {
return KVOObservable(object: self.base, keyPath: keyPath, options: options, retainTarget: retainSelf).asObservable()
}
2、KVOObservable实现了ObservableType协议,所以自己实现了subscribe方法,并且创建了一个KVOObserver观察者
init(object: AnyObject, keyPath: String, options: KeyValueObservingOptions, retainTarget: Bool) {
self.target = object
self.keyPath = keyPath
self.options = options
self.retainTarget = retainTarget
if retainTarget {
self.strongTarget = object
}
}
func subscribe<Observer: ObserverType>(_ observer: Observer) -> Disposable where Observer.Element == Element? {
let observer = KVOObserver(parent: self) { value in
if value as? NSNull != nil {
observer.on(.next(nil))
return
}
observer.on(.next(value as? Element))
}
return Disposables.create(with: observer.dispose)
3、KVOObserver继承了一个OC类_RXKVOObserver,实现了Disposable协议。在init方法和dispose方法中都是调用了父类的实现
4、_RXKVOObserver实际上就是对OC中KVO实现的封装使用,将_RXKVOObserver变成target的观察者,在dispose方法中移除观察者
-(instancetype)initWithTarget:(id)target
retainTarget:(BOOL)retainTarget
keyPath:(NSString*)keyPath
options:(NSKeyValueObservingOptions)options
callback:(void (^)(id))callback {
// 省略
self.keyPath = keyPath;
self.callback = callback;
[self.target addObserver:self forKeyPath:self.keyPath options:options context:nil];
return self;
}
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
@synchronized(self) {
self.callback(change[NSKeyValueChangeNewKey]);
}
}
-(void)dispose {
[self.target removeObserver:self forKeyPath:self.keyPath context:nil];
self.target = nil;
self.retainedTarget = nil;
}
5、当创建的序列订阅subscribe时候就会来到KVOObservable的subscribe方法
6、当观察的属性值发生变化的时候就回来到_RXKVOObserver类的observeValueForKeyPath方法,然后触发KVOObserver的闭包,观察者发送next事件
observer.on(.next(value as? Element))
7、这个时候就会来到刚开始订阅的onNext事件闭包回调
8、关于销毁,这个序列的销毁者是加入到disposeBag中的,只有当disposeBag对象销毁的时候,就会对disposeBag中保存的销毁者调用dispose()方法,这个时候就会触发_RXKVOObserver中的dispose方法移除销毁者。
上一篇: iOS KVC底层实现
下一篇: KVC、KVO小结