就问此时此刻还有谁?45度仰望天空,该死!我这无处安放的魅力!编程
- RxSwift(1)— 初探
- RxSwift(2)— 核心逻辑源码分析
- RxSwift(3)— Observable序列的建立方式
- RxSwift(4)— 高阶函数(上)
- RxSwift(5)— 高阶函数(下)
- RxSwift(6)— 调度者-scheduler源码解析(上)
- RxSwift(7)— 调度者-scheduler源码解析(下)
- RxSwift(8)— KVO底层探索(上)
- RxSwift(9)— KVO底层探索(下)
- RxSwift(10)— 场景序列总结
- RxSwift(11)— dispose源码解析
- RxSwift(12)— Subject即攻也守
- RxSwift(13)— 爬过的坑
- RxSwift(14)— MVVM双向绑定
RxSwift 目录直通车 --- 和谐学习,不急不躁!swift
上面一篇章咱们对
KVO
底层有了必定了解!这一篇咱们就开始分析RxSwift
对KVO
的封装,看完这一篇,你估计也会由衷的感慨:底层源码的思路是有相同的闭包
RxSwift
对KVO
的调用主要有两种方式:ide
rx.observe
:更加高效,由于它是一个 KVO 机制的简单封装。rx.observeWeakly
: 执行效率要低一些,由于它要处理对象的释放防止弱引用(对象的 dealloc 关系)。应用场景:函数
rx.observe
的地方均可以使用 rx.observeWeakly
。rx.observe
时路径只能包括 strong 属性
,不然就会有系统崩溃的风险。而 rx.observeWeakly
能够用在 weak
属性上。self.person.rx.observeWeakly(String.self, "name")
.subscribe(onNext: { (change) in
print("observeWeakly订阅到了KVO:\(String(describing: change))")
}).disposed(by: disposeBag)
复制代码
使用起来很是简单,可读性高,免去传统KVO带来的恶心!下面也粘贴出代码对比一下源码分析
// 1: 添加观察
person.addObserver(self, forKeyPath: "name", options: .new, context: nil)
// 2: 观察响应回调
override func observeValue(forKeyPath keyPath:, of object:, change: , context:){} // 3: 移除观察 person.removeObserver(self, forKeyPath: "name")
复制代码
首先分析在RxSwift
的世界必然是由序列的,第一步分析序列的建立post
self.person.rx.observeWeakly(String.self, "name")
复制代码
中间的细节流程过滤,你们本身查看源码!咱们直奔核心,立刻要上课!哈哈哈~~~~~~学习
let observable = observeWeaklyKeyPathFor(target, keyPathSections: components, options: options)
.finishWithNilWhenDealloc(target)
复制代码
observeWeaklyKeyPathFor
内部建立序列finishWithNilWhenDealloc
针对提早释放的变量的容错,若是对象释放,也就没有观察的必要,写的很错,毕竟可以观察weak
修饰对象weak var weakTarget: AnyObject? = target
let propertyName = keyPathSections[0]
let remainingPaths = Array(keyPathSections[1..<keyPathSections.count])
let property = class_getProperty(object_getClass(target), propertyName)
if property == nil {
return Observable.error(RxCocoaError.invalidPropertyName(object: target, propertyName: propertyName))
}
let propertyAttributes = property_getAttributes(property!)
// should dealloc hook be in place if week property, or just create strong reference because it doesn't matter
let isWeak = isWeakProperty(propertyAttributes.map(String.init) ?? "")
let propertyObservable = KVOObservable(object: target, keyPath: propertyName, options: options.union(.initial), retainTarget: false) as KVOObservable<AnyObject>
复制代码
keyPath
进行处理分析KVOObservable
就是咱们的KVO观察的序列,这个对象继承ObservableType
,让其具有序列的特性。实现KVOObservableProtocol
协议,拓展几个协议属性,常规面向协议编程的思路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
}
}
复制代码
flatMapLatest
的封装容错常规订阅,提供给内部:AnonymousObserver
,这里不讲了,前面的流程很是简单---直接分析重点ui
func subscribe(_ observer: Observer) -> Disposable {
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)
}
复制代码
KVOObserver
class KVOObserver: _RXKVOObserver, Disposable 复制代码
_RXKVOObserver
,咱们查看内部,个人天啊!居然是一个OC类Disposable
协议,具有销毁的能力,用来干吗,等会讲解-(instancetype)initWithTarget:(id)target
retainTarget:(BOOL)retainTarget
keyPath:(NSString*)keyPath
options:(NSKeyValueObservingOptions)options
callback:(void (^)(id))callback {
self = [super init];
if (!self) return nil;
self.target = target;
if (retainTarget) {
self.retainedTarget = target;
}
self.keyPath = keyPath;
self.callback = callback;
// 核心骚操做
[self.target addObserver:self forKeyPath:self.keyPath options:options context:nil];
return self;
}
复制代码
KVO
信息处理保存,callback
回调的保存,函数式思想[self.target addObserver:self forKeyPath:self.keyPath options:options context:nil];
这段代码是比较骚,核心逻辑:观察者移交,咱们不在是VC观察,使咱们内部类!keypath
有了变化,必然胡响应下面的方法-(void)observeValueForKeyPath: ofObject: change: context: {
@synchronized(self) {
self.callback(change[NSKeyValueChangeNewKey]);
}
}
复制代码
self.callback(change[NSKeyValueChangeNewKey])
,那么咱们的流程就会流到以前的对象初始化时候的闭包let observer = KVOObserver(parent: self) { value in
if value as? NSNull != nil {
observer.on(.next(nil))
return
}
observer.on(.next(value as? Element))
}
复制代码
KVO
回调的change
,完美!序列订阅得以响应下面还缺一个点:关于KVO
在RxSwift
的世界里面是不须要移除观察的,下面开始解析spa
override func dispose() {
super.dispose()
self.retainSelf = nil
}
复制代码
dispose
的流程是很是简单了,前面咱们也有相关分析super.dispose()
-(void)dispose {
[self.target removeObserver:self forKeyPath:self.keyPath context:nil];
self.target = nil;
self.retainedTarget = nil;
}
复制代码
dispose
纵观RxSwift的KVO流程也就是中间者模式! 移交观察者,到达响应效果。
就问此时此刻还有谁?45度仰望天空,该死!我这无处安放的魅力!