RxSwift
對KVO
的調用主要有兩種方式:
-
rx.observe
:更加高效,因為它是一個 KVO 機制的簡單封裝。 -
rx.observeWeakly
: 執行效率要低一些,因為它要判斷對象是否被釋放
應用場景:
- 在可以使用
rx.observe
的地方都可以使用rx.observeWeakly
。 - 使用
rx.observe
時路徑只能包括 strong 屬性,否則就會有系統崩潰的風險。而rx.observeWeakly
可以用在weak
屬性上。
RxSwift 的KVO比原生KVO用法方便的多:
person.rx.observeWeakly(String.self, "name")
.subscribe(onNext: { (str) in
print("訂閱到KVO:\(str)")
})
.disposed(by: disposebag)
同樣,KVO分為四個流程:創建序列、訂閱、發送、銷毀
創建序列
let observable = observeWeaklyKeyPathFor(target, keyPathSections: components, options: options)
.finishWithNilWhenDealloc(target)
-
finishWithNilWhenDealloc(target)
對target進行處理,如果target被釋放,則發送nil消息,銷毀序列 -
observeWeaklyKeyPathFor
創建一個序列
let property = class_getProperty(object_getClass(target), propertyName)
let propertyAttributes = property_getAttributes(property!)
//propertyAttributes: T@"NSString",N,C,Vname
這2步獲取了target(student)
所監聽的屬性(name)
的屬性,即:NSString
類型,N:nonatomic
,C:copy
。如果是W
的話,則代表weak
//創建KVOObservable
let propertyObservable = KVOObservable(object: target, keyPath: propertyName, options: options.union(.initial), retainTarget: false) as KVOObservable<AnyObject>
訂閱、發送流程
//KVOObservable:
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)
}
subscribe
創建一個KVOObserver
,繼承自:_RXKVOObserver
從下面代碼可以看出,RxSwift-KVO其實是對OC的KVO的封裝,觀察者為KVOObserver
//OC的添加觀察
[self.target addObserver:self forKeyPath:self.keyPath options:options context:nil];
//回調方法
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
@synchronized(self) {
self.callback(change[NSKeyValueChangeNewKey]);
}
}
當keyPath的值改變時,執行代理方法,回調callback
銷毀
KVO的銷毀實際意義就是KVOObserver
的disopose()
-(void)dispose {
[self.target removeObserver:self forKeyPath:self.keyPath context:nil];
self.target = nil;
self.retainedTarget = nil;
}
總結:
RxSwift-KVO
實際是對OC KVO
的封裝,以中間者模式把觀察者移交給KVOObserver
,最后回調響應事件