@TOC
RxSwift序列核心邏輯
上一篇博客:Rxswift學習之(一)函數響應式編程思想只是簡單的分析了序列的核心邏輯。本篇博客主要針對上一篇做一下更加深入的探討,如果有那些地方分析有誤,還請留言:QQ:282889543,讓我們彼此提高,彼此成就。
總的來說分析Rxswift的核心邏輯還是按照三部曲:創建序列,訂閱序列,銷毀序列。核心思想是萬物皆序列。
1. 序列的創建
Observable可觀察者序列
我們先來看下創建Observable所涉及的類的繼承關系:
如下圖:
針對上面的類圖,簡單分析下類的關系和設計思想:
首先分層實施的很徹底,每一層都只解決一件事情,一層層疊起來結構非常清晰:
AnonymousObservable
-> Producer
-> Observable
-> ObservableType
-> ObservableConvertibleType
其次我們簡單分解一下每個類都做了些什么:
-
ObservableConvertibleType:顧名思義即可轉換為
Observable
類型協議,方法只有一個asObservable
,這有什么好處呢?
- 用戶不需要關注其具體是哪個類型對象
- 讓用戶更多的關注其核心功能
-
ObservableType:也是個協議,繼承了ObservableConvertibleType協議的
asObservable
,它提供抽象方法subscribe,即我們常說的訂閱,只有外部訂閱了該對象,才能真正實現對該對象進行觀察。 -
Observable:真正的類,可以稱之為元類,對于用戶來說Observable 的功能是完整的,因為它已經具備了所有的用戶所需要的功能,盡管有些方法并沒有得到實現仍是抽象方法。
Producer: 它繼承了Observable
的所有方法,并實現subscribe 方法 -
AnonymousObservable:它繼承了
Producer
的所有方法,并且增加了屬性let _subscribeHandler: SubscribeHandler
用來保存創建序列時傳入的閉包,也就相對于擁有了調用這個序列的能力,此外它還實現run方法,這也是創建序列最核心關鍵的方法。在run()方法中它創建一個AnonymousObservableSink
final private類的對象,而這個對象sink可以稱之為管子,它類似于manager的角色,擁有序列和訂閱,銷毀能力。這里有兩個疑惑:
問題1.
AnonymousObservableSink
為什么要定義成final private類,不能被繼承,也不能被外部訪問?
問題2. 創建的Observable
是如何關聯到訂閱的?
這兩個問題我們后面再分析。
最后,我們總結一下設計思想:
事實上用戶所使用的
Observable
,都是Producer
的子類和AnonymousObservable
平行的子類,只不過用戶不需要關心其具體實現罷了
每一個類似AnonymousObservable
的類,還有一個與之相關的類AnonymousObservableSink
,Sink即管道,所有這些組合起來才能讓其真正運行起來,AnonymousObservableSink
同時擁有序列,訂閱功能,類似于我們項目中經常用的manager角色。
整個設計向上通過組合協議的方式描述其特性,向下通過子類化的方式屏蔽其實現細節,類似于工廠模式,這樣的類也可以叫類簇。
序列創建的流程
通過上面類繼承關系,其實我們不難理解序列的創建流程,它確實也是只有比較簡單的幾部,寥寥幾行代碼就搞定了,難點是上面拋出的幾個問題:
下面我們將通過一個簡單的Rxswift的實例來分析一下序列的創建,訂閱,銷毀直接的流程和關系。
實例1:
//1. 創建序列
let ob = Observable<Any>.create { (obserber) -> Disposable in
// 3:發送信號
obserber.onNext("kyl發送了信號")
obserber.onCompleted()
return Disposables.create()
}
// 2:訂閱信號
let _ = ob.subscribe(onNext: { (text) in
print("訂閱到:\(text)")
}, onError: { (error) in
print("error: \(error)")
}, onCompleted: {
print("完成")
}) {
print("銷毀")
}
上面實例1 的這段代碼可以用酷C老師的一個圖來清晰的表達:
從上面的代碼和關系圖,我們可能會產生這樣一個疑惑:
問題3: 創建的ob序列,僅僅只是通過
ob.subscribe()
訂閱了一下,為什么我們在ob創建時的尾隨閉包(我們這里給個名字叫閉包A
)里面調用了obserber.onNext("kyl發送了信號")
這個代碼,我們就可以訂閱到let _ = ob.subscribe(onNext: { (text) in print("訂閱到:\(text)") }
這里會打印:”訂閱到:kyl發送了信號“。我們沒有看見他們之間有任何關聯,怎么ob發送消息,subcribe()的onNext閉包就可以觸發呢,這是為什么呢?
我們可以這里可以簡單推理下:ob.subscribe()這個訂閱方法肯定做了一些事情,在某個地方調用了閉包A
,才能實現這個功能。具體是怎么樣實現的呢?下面我們將通過分析源碼來解答這個疑惑。
從上面的代碼我們可以知道,創建序列就一行代碼:let ob = Observable<Any>.create { (obserber) ->
而這一行代碼其實是做了好多事情的。
首先我們通過一個流程圖來初略的了解一下序列創建流程:
創建序列的Rxswift原碼很簡單,從上圖可以看出,直接一行代碼return AnonymousObservable(subscribe)
就結束了,這里我們們并沒有找到我們需要的答案,甚至我們有點越來越暈感覺。
- AnonymousObservable類源碼
final private class AnonymousObservable<Element>: Producer<Element> {
typealias SubscribeHandler = (AnyObserver<Element>) -> Disposable
let _subscribeHandler: SubscribeHandler
init(_ subscribeHandler: @escaping SubscribeHandler) {
self._subscribeHandler = subscribeHandler
}
override func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element {
let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
let subscription = sink.run(self)
return (sink: sink, subscription: subscription)
}
}
我們先做個深呼吸,放輕松,此路不通那我們來嘗試分析其他方向,不能在一棵樹上吊死。下面我們來分析一下訂閱的流程。
2.訂閱
回顧上面實例1中的訂閱代碼:let _ = ob.subscribe(onNext: { (text) in
這行代碼又做了些什么事情呢?下面我們通過源碼來深入分析一下:
- Rxswift訂閱
subscribe()
的源碼如下:
public func subscribe(onNext: ((E) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
-> Disposable {
... 上面代碼不是我們要分析的重點,...表示忽略了此次的一段源碼
/*注意,此次定義了一個AnonymousObserver()對象,以參數的形式,
構造方法里面傳入了一個尾隨閉包eventHandler,
在這個閉包里面,當收到event的不同事件,
會觸發并調用,我們 `let _ = ob.subscribe(onNext: { (text) in` 這個方法傳入閉包
*/
let observer = AnonymousObserver<E> { event in
...
switch event {
case .next(let value):
onNext?(value) //調用訂閱時傳入的ob.subscribe(onNext:閉包
case .error(let error):
if let onError = onError {
onError(error)//調用訂閱時傳入的ob.subscribe(onError:閉包
}
else {
Hooks.defaultErrorHandler(callStack, error)
}
disposable.dispose()
case .completed:
onCompleted?()//調用訂閱時傳入的ob.subscribe(onCompleted:閉包
disposable.dispose()
}
}
return Disposables.create(
self.asObservable().subscribe(observer),
disposable
)/*這里直接返回了Disposables對象,用來釋放資源,
在它的構造函數里面直接調用了self.asObservable().subscribe(observer),
而asObservable()就是我們創建的序列ob,也就是ob.subscribe(),
并傳入了,在這段代碼里面創建的局部變量let observer = AnonymousObserver<E>,*/
}
通過上面源碼我們可以知道:subscribe()這個方法,以參數的形式傳入了onNext()閉包,onError()閉包,onComplete()閉包,在函數里面創建了一個AnonymousObserver對象observer,這個對象創建的時候傳入了一個閉包,當收到不同event事件時,會分別調用我們subscribe()傳入的onNext,onError,onComplete這三個閉包。最重要一點是return Disposables.create( self.asObservable().subscribe(observer), disposable )
這句代碼調用了我們真正的subscribe()函數,并以參數的形式傳入了AnonymousObserver對象,self.asObservable()就是我們create()函數創建的序列ob, 而到此處我們可以清晰的看到,我們訂閱時傳入參數閉包和我們創建的ob建立了一個鏈條。
這里我們又有一個疑問:self.asObservable()為什么就是我們create()函數返回的ob呢?
要解答這個問題,我需要回顧一下上面分析的Observable類的繼承關系:Observable
-> ObservableType
-> ObservableConvertibleType
即Observable繼承ObservableType協議,ObservableType又繼承ObservableConvertibleType協議,而我們的ObservableConvertibleType提供了抽象方法asObservable(),我們Observable類中實現了asObservable()這個方法,它直接返回self就它自己。
下面通過源碼來證實:
///
/// It represents a push style sequence.
public class Observable<Element> : ObservableType {
...
public func asObservable() -> Observable<E> {
return self
}
...
}
分析了Rxswift訂閱subscribe()
的源碼感覺非常nice, 我們找到了我們ob 創建時傳入的閉包和我們訂閱時的閉包存在了一條鏈條關系,也就是只要ob發送了消息,那我們的訂閱者一定可以按照這個鏈條收到消息。但是我們還是不知道到底是怎么調用的,怎么觸發的。
而且我們注意到self.asObservable().subscribe(observer)
也就是AnonymousObservable
調用了subscribe()
方法,但是在AnonymousObservable
類中我們并沒有找到subscribe()的定義,所以我們需要來看他的父類Producer
- Producer的源碼如下:
class Producer<Element> : Observable<Element> {
override init() {
super.init()
}
override func subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E == Element {
if !CurrentThreadScheduler.isScheduleRequired {
// The returned disposable needs to release all references once it was disposed.
let disposer = SinkDisposer()
/*重點在這里了,這里調用了run()方法,一切疑惑都清晰了,我們知道了run()調用時傳入了observer,并且創建了sink管子,而這個管子具備了序列的功能,可以調用on()方法。
*/
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
return disposer
}
else {
return CurrentThreadScheduler.instance.schedule(()) { _ in
let disposer = SinkDisposer()
let sinkAndSubscription = self.run(observer, cancel: disposer)
disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)
return disposer
}
}
}
func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element {
rxAbstractMethod()
}
}
果然不出我們所料,在Producer
中我們找到了subscribe()的方法定義,到此我們可以總結出很清晰的幾條線索了:
- (1)通過前面的類繼承關系可以知道是
Producer
實現了ObservableType
協議的subscribe()方法。在這個方法里面調用了self.run(observer, cancel: disposer)
- (2) self.run()實際上就是AnonymousObservable.run(), 這這個方法里面做了三件事情:
override func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element {
//1.創建了一個sink管道對象,并將observer也就create()創建
//序列時傳入的閉包傳給了sink
let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
//2. sink調用自己的run()方法,并把AnonymousObservable作為參數傳入。
let subscription = sink.run(self)
//返回一個元組,包含sink管道信息。
return (sink: sink, subscription: subscription)
}
- (3)AnonymousObservableSink類中run()方法中調用
parent._subscribeHandler(AnyObserver(self))
其中parent就是我們(2)中sink.run(self)
傳入的self,也就是AnonymousObservable對象;并且我們前面已經知道_subscribeHandler就是創建序列時保存的那個通過create()函數參數傳入的 閉包:let ob = Observable<Any>.create { (obserber) -> Disposable in // 3:發送信號 obserber.onNext("kyl發送了信號") obserber.onCompleted() return Disposables.create() }
。 現在已經很清晰了parent._subscribeHandler(AnyObserver(self))
執行閉包,這行代碼就會調用obserber.onNext("kyl發送了信號")
這個行代碼。
- 現在我們可以通過一個流程圖來總結我們代碼執行的流程:
上面的訂閱序列流程分析:我們弄明白了從訂閱序列到調用create()函數時傳入的參數閉包調用的邏輯,但是這個閉包發送onNext()信號后,怎么到訂閱消息的onNext()閉包我們還不是很清晰。因此我們需要分析AnonymousObserver
我們先來看下AnonymousObserver
類
-
AnonymousObserver
源碼定義如下:
final class AnonymousObserver<ElementType> : ObserverBase<ElementType> {
typealias Element = ElementType
typealias EventHandler = (Event<Element>) -> Void
private let _eventHandler : EventHandler
/*構造函數,保存了EventHandler尾隨閉包*/
init(_ eventHandler: @escaping EventHandler) {
#if TRACE_RESOURCES
_ = Resources.incrementTotal()
#endif
self._eventHandler = eventHandler
}
//覆寫了onCore方法,調用了EventHandler閉包
override func onCore(_ event: Event<Element>) {
return self._eventHandler(event)
}
#if TRACE_RESOURCES
deinit {
_ = Resources.decrementTotal()
}
#endif
}
從AnonymousObserver
源碼中我們并沒有找到onNext()方法,那我們只能沿著它的繼承鏈往上查找,這里需要了解一下類的繼承關系:
- AnonymousObserver的繼承關系:
通過分析類的繼承關系,我們得知:這樣一個關系鏈:
AnonymousObserver對象的on()方法會調用onCore()方法,ObserverType里面有onNext,onError,onComplete方法。但是on()是如何調用的,何時調用的呢?
要解決這個疑問,我們需要再次回到我們創建序列的代碼:
public static func create(_ subscribe: @escaping (AnyObserver<E>) -> Disposable) -> Observable<E> {
return AnonymousObservable(subscribe)
}
創建序列的create()方法傳入了一個subscribe閉包,并返回了AnonymousObservable對象。其中subscribe閉包就是我們序列創建時參數形式傳入 閉包。并且AnonymousObservable初始化時將這個閉包保存起來了self._subscribeHandler = subscribeHandler
AnonymousObservable 有一個run()方法,run方法里面創建了一個AnonymousObservableSink
對象sink,具體源碼如下:
final private class AnonymousObservable<Element>: Producer<Element> {
typealias SubscribeHandler = (AnyObserver<Element>) -> Disposable
let _subscribeHandler: SubscribeHandler
init(_ subscribeHandler: @escaping SubscribeHandler) {
self._subscribeHandler = subscribeHandler
}
override func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element {
let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
let subscription = sink.run(self)
return (sink: sink, subscription: subscription)
}
}
分析了這么久,繞了一圈,終于發現關鍵就在AnonymousObservableSink
管子這個對象里面了。sink這是個神奇的管子。它就保存了序列,也保存了訂閱,還保存了用于銷毀的disposed 也就是同時擁有了創建序列,訂閱序列,銷毀序列功能。
我們來分析下AnonymousObservableSink
的源碼:
final private class AnonymousObservableSink<O: ObserverType>: Sink<O>, ObserverType {
typealias E = O.E
//這里的Parent就是我們上面分析的AnonymousObservable,非常重要
typealias Parent = AnonymousObservable<E>
// state
private let _isStopped = AtomicInt(0)
#if DEBUG
fileprivate let _synchronizationTracker = SynchronizationTracker()
#endif
// 構造方法,傳入了observer序列,和Cancelable
override init(observer: O, cancel: Cancelable) {
super.init(observer: observer, cancel: cancel)
}
//這里實現 了ObserverType協議的on()方法
func on(_ event: Event<E>) {
#if DEBUG
self._synchronizationTracker.register(synchronizationErrorMessage: .default)
defer { self._synchronizationTracker.unregister() }
#endif
switch event {
case .next:
if load(self._isStopped) == 1 {
return
}
//調用了父類的發布,self.forwardOn()會調用自己的on()方法
self.forwardOn(event)
case .error, .completed:
if fetchOr(self._isStopped, 1) == 0 {
self.forwardOn(event)
self.dispose()
}
}
}
func run(_ parent: Parent) -> Disposable {
/*調用了_subscribeHandler閉包,這個閉包就是我們之前創建序列時傳入閉包。
parent就是傳入進來的序列,這里序列的閉包里傳入了self并且強轉為AnyObserver
這里將self傳給了閉包_subscribeHandler,這樣_subscribeHandler也就具備了subcribe的能力。
*/
return parent._subscribeHandler(AnyObserver(self))
}
}
其中Sink類的源碼如下:
class Sink<O : ObserverType> : Disposable {
fileprivate let _observer: O
fileprivate let _cancel: Cancelable
fileprivate let _disposed = AtomicInt(0)
#if DEBUG
fileprivate let _synchronizationTracker = SynchronizationTracker()
#endif
init(observer: O, cancel: Cancelable) {
#if TRACE_RESOURCES
_ = Resources.incrementTotal()
#endif
self._observer = observer
self._cancel = cancel
}
final func forwardOn(_ event: Event<O.E>) {
#if DEBUG
self._synchronizationTracker.register(synchronizationErrorMessage: .default)
defer { self._synchronizationTracker.unregister() }
#endif
if isFlagSet(self._disposed, 1) {
return
}
//這里調用了傳入observer.on()方法,
self._observer.on(event)
}
final func forwarder() -> SinkForward<O> {
return SinkForward(forward: self)
}
final var disposed: Bool {
return isFlagSet(self._disposed, 1)
}
func dispose() {
fetchOr(self._disposed, 1)
self._cancel.dispose()
}
deinit {
#if TRACE_RESOURCES
_ = Resources.decrementTotal()
#endif
}
}
從源碼分析我們得知:
我們的sink保存了我們的序列,當我們調用ob.onNext()發送信號時,由于我們的sink已經持有了ob, 這樣sink會調用on()方法,在on()方法里面會調用self.forwardOn(event),而在fowardOn()里面會調用self._observer.on(event)。這樣我的疑問就解決了,答案就是sink調用了on()方法。
這里我們再來總結一下總的流程:
- 創建序列時
create()
返回了一個ob
, 這個ob就是序列,創建的時候傳遞了一個閉包A
。在閉包A中調用了ob.onNext()
發送了信號。 - 訂閱序列時調用
ob.subscribe()
方法,這個方法會創建一個AnonymousObserver
對象,并調用了self.asObservable().subscribe(observer)
。 -
self.asObservable()
實際就是我們的ob
, 也就是ob調用了subscribe().而AnonymousObserver中沒有找到subscribe()。 - 我們在
AnonymousObserver
的父類中找到了subscribe(),發現subscribe()調用了AnonymousObserver的run()
方法。 - 在AnonymousObserver的run()方法中,創建了一個管子sink,并調用了
sink.run(self)
,sink是AnonymousObservableSink的對象,而在sink的run()方法中parent._subscribeHandler(AnyObserver(self))
調用了創建序列時保存的閉包A (parent就是AnonymousObserver),這樣就解釋了訂閱時,回調了A閉包的原因。 - 至于怎么調用onNext()方法也是通過sink來實現的。
- sink已經持有了ob ,當我們在A閉包里面調用ob.onNext()發送信號時,實際會通過sink.on()來調用。首先sink.on()會調用forwardOn().
- 在forwardOn()中會調用self._observer.on(event)。
- _observer.on()會調用_observer.onCore()
- _observer.onCore(event)會根據event的類型判斷是調用onNext(),onError(),onComplete()中間一個,由于我們傳遞的是onNext事件,所以會調用onNext() ,而這個_observer.onNext()會調用我們訂閱時傳入閉包subscribe(onNext:).
- 為什么回調的原因是:
public func subscribe(onNext: ((E) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
-> Disposable {
... 上面代碼不是我們要分析的重點,...表示忽略了此次的一段源碼
/*注意,此次定義了一個AnonymousObserver()對象,以參數的形式,
構造方法里面傳入了一個尾隨閉包eventHandler,
在這個閉包里面,當收到event的不同事件,
會觸發并調用,我們 `let _ = ob.subscribe(onNext: { (text) in` 這個方法傳入閉包
*/
let observer = AnonymousObserver<E> { event in
...
switch event {
case .next(let value):
onNext?(value) //調用訂閱時傳入的
這里調用ob.subscribe()的時候,我們創建了AnonymousObserver和我們subscribe()傳入的onNext()閉包做了一個綁定,當AnonymousObserver.onNext()
調用的時候必定會回調subscribe()傳入的onNext()閉包。而10中的_observer對象指的就是let observer = AnonymousObserver
- 還是通過這張圖來解釋最簡潔: