欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

RxSwift KVO的实现原理

程序员文章站 2024-03-24 13:50:58
...

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)
  • 源码流程分析图

RxSwift KVO的实现原理

  • 源码分析

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