一、Swift是一種靜態語言。靜態語言對於數值的傳遞、響應的回調、通信等有必定的影響。不像OC有運行時,能夠動態的發送消息。因此須要RXSwift來彌補靜態語言上的不足。html
二、RxSwift的思想是函數響應式編程,很符合Swift函數是一等公民的設計思想,也是之後Swift發展的方向。react
三、RxSwift是ReactiveX家族的一員。瞭解RxSwift後,能夠拓展到ReactiveX家族的其餘框架。編程
一、函數式swift
函數來源於數學,用 y = f(x)
表示,其中,y是因變量,x是自變量。y會隨着x的變化而變化。設計模式
在swift中,x至關於一個參數,f是函數,y就是函數的結果—返回值。閉包
在必定狀況下,x能夠表示爲 x = f(x)
,則,上面的公式能夠變形爲 y = f(f(x))
。即一個函數的參數能夠是另外一個函數。增長了函數的靈活性。 這就是函數式編程的核心思想。框架
二、函數響應式函數式編程
舉例說明:函數
var a: Int = 10
var b: Int = a + 10
複製代碼
若是上面的代碼中 b 的值須要一直跟隨a的值發生變化,咱們須要怎麼來實現呢?咱們須要監聽a的值變化,而b響應a的變化而變化。這就是OC中的KVO機制。源碼分析
可是,很遺憾,Swift中沒有KVO鍵值監聽。因此,咱們須要RxSwift來實現更高級更方便的函數響應式編程。
self.person.rx.observeWeakly(String.self, "name")
.subscribe(onNext:{(value) in
print(value as Any)
})
.disposed(by: disposeBag)
複製代碼
self.button.rx.tap
.subscribe(onNext: {(value) in
print("點擊了按鈕")
})
.disposed(by: disposeBag)
複製代碼
self.textFiled.rx.text.orEmpty
.subscribe(onNext: {(text) in
print(text)
})
.disposed(by: disposeBag)
複製代碼
self.textFiled.rx.text
.bind(to: self.button.rx.title())
.disposed(by: disposeBag)
複製代碼
let tap = UITapGestureRecognizer()
self.label.addGestureRecognizer(tap)
self.label.isUserInteractionEnable = true
tap.rx.event.subscribe(onNext: {(tap) in
print(tap.view)
})
.disposed(by: disposeBag)
複製代碼
NotificationCenter.default.rx.notifcation(UIResponder.keyboardWillShowNotification)
.subscribe(onNext: {(noti) in
print(noti)
})
.disposed(by: disposeBag)
複製代碼
timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
timer.subscribe(onNext: {(num) in
print(num)
})
.disposed(by: disposeBag)
複製代碼
第一步:建立序列
let ob = Observable<String>.create { (observer) -> Disposable in
return Disposables.create()
}
複製代碼
第二步:訂閱信號
let _ = ob.subscribe(onNext: { (text) in
print("訂閱信息: \(text)")
}, onError: { (error) in
print("error: \(error)")
}, onCompleted: {
print("訂閱結束")
}) {
print("已銷燬")
}
複製代碼
第三步:發送信號
let ob = Observable<String>.create { (observer) -> Disposable in
// 第三步:發送信號
observer.onNext("信息1")
return Disposables.create()
}
複製代碼
查看RxSwift源碼
發現好像沒有內部實現,只有一個函數聲明,那咱們去哪裏查看實現呢?喬布斯曾經說過,看源碼不只要看代碼,還要看文檔註釋!!!因此咱們往上看註釋,會發現有一個「seealso」,翻譯過來是「另見」。咦,彷佛是須要查看其餘文檔的意思。而且後面跟了一個連接,那咱們是要去看文檔嗎?
咱們先來分析一下這個連接,reactivex.io/documentati…,最後指向了一個create文件的html,那咱們猜想是不是源碼中有一個Create文件呢,咱們如今項目中來搜索一下
搜索後發現確實有一個Create文件,點進去看一下 能找到一個ObservableType的擴展,實現了一個create方法。其返回值爲AnonymousObservable(subscribe)。一個內部匿名可觀察序列類。參數subscribe則爲第一步建立序列中的閉包。
同時,在這個文件的下方能找到AnonymousObservable匿名內部可觀察序列類的實現
實現很簡單,init初始化時保存了傳入的閉包,至此,第一步建立序列完成。找到源碼
分析發現,藍色框之外的代碼做用是回收,真正訂閱的關鍵代碼是藍色方框之內的代碼。那咱們主要看一下這一部分。 首先建立了一個匿名的觀察者AnonymousObserver,其實現和匿名可觀察序列相似,都是保存建立時的閉包。函數結束時return一個Disposables對象。分析到這裏你們是否是以爲很奇怪?第一步的可觀察序列有了,第二步的觀察者也有了,可是他們之間彷佛沒有聯繫啊,怎麼訂閱的?以及第三步的發送信號又是如何執行的呢?
咱們找來找去,彷佛只可能在
這句代碼中,好,咱們一塊兒去驗證一下咱們的猜測。self.asObservable().subscribe(observer)
複製代碼
咱們先看看asObservable(),點擊查看一下,咦,點不進去。咱們再點查看一下subscribe(observer),咦,好像也找不到實現。好吧,咱們再往前看是self,self咱們知道是第一步建立的可觀察序列
在這個類裏面,咱們找到了asObservable()
和
subscribe
函數,
asObservable()
的做用僅僅是返回自身self。
咱們再看看subscribe
方法。 內部調用了rxAbstractMethod()
方法。可是通過查看,這個方法並無被實現。分析到這裏又分析不下去了。咱們再回想一下,Observable對象是由create
方法建立的。而且其內部是初始化了一個內部匿名可觀察序列的實例對象。咱們再回到Create文件查看一下源碼。發現其也沒有subscribe
函數。
可是能夠發現,AnonymousObservable
類是繼承至Producer
類,那subscribe
函數會不會是其父類Producer
的方法呢?
經過查看源碼
Producer
對象有
subscribe
函數而且經過斷點運行會發現,會走到else中的方法。調用了
self.run(observer, cancel: disposer)
。
在下方找到run
函數。發現其內部只有一個rxAbstractMethod()
函數調用。真正的run
函數並無實現。其實,這是一種設計模式。有好奇心的寶寶能夠自行了解一下。這裏就不展開敘述了。這個run
函數其實剛纔咱們已將看到過了,Producer
對象的子類AnonymousObservable
匿名可觀察序列類裏
在這個方法中,傳入了以前建立的匿名觀察者AnonymousObserver實例對象。而且建立了一個AnonymousObservableSink
實例對象,並調用了它的run()
函數。咱們看一下這個run()
函數的實現。實際上是調用了parent._subscribeHandler(AnyObserver(self))
。parent
就是AnonymousObservable
的實例。也就是調用了AnonymousObservable._subscribeHandler(AnyObserver(self))
。
咱們在分析第一步建立可觀察序列的時候已經知道,這裏的_subscribeHandler
保存的其實就是第一步建立可觀察序列傳入的閉包。如今調用_subscribeHandler
便是執行了這個閉包。而閉包中的方法就是第三步發送信號
。
通過上面的源碼分析,已經知道了從建立可觀察序列-->訂閱信號-->發送信號這一系列的數據流轉過程。
observer.onNext()
函數發送信號。以前已經分析過了,在第二步訂閱信號的時候,建立了一個內部匿名觀察者observer
。這個observer
又是如何傳遞給第一步建立序列的閉包中的呢?下面咱們就來分析一下。
咱們知道,在第二步訂閱信號調用subscribe
的return中,調用了Producer
對象的subscribe
函數,並將observer
做爲參數傳遞過去。而在subscribe
函數中調用子類AnonymousObservable
匿名可觀察序列類的run
函數時,將observer
做爲參數傳遞到了run
函數中。
在AnonymousObservable.run
函數中,初始化AnonymousObservableSink
實例時,又將observer
傳遞給了AnonymousObservableSink
實例對象。並在調用run
函數時,經過AnonymousObservableSink
實例對象建立AnyObserver
實例,從而傳遞到了建立序列的閉包中,獲得一個觀察者observer
。
經過調用觀察者observer
對象的onNext()
函數,便可調用到第二步訂閱信號閉包中的onNext
回調。從而發送已經傳遞訂閱信息。
通過上面的分析過程,RxSwift的源碼已經分析完畢。RxSwift的核心原理也瞭解得比較清晰。可是,RxSwift中所用到的設計模式已經編程思想倒是須要咱們在之後的使用中不斷學習已經掌握的。
最後,附上RxSwift的一個源碼分析思惟導圖,但願對你們有所幫助。