RxSwift 內(nèi)部是如何運(yùn)行的,Observable 與 Observer 之間存在什么關(guān)系,Operator 又是如何實(shí)現(xiàn)的,如果想徹底弄清楚 RxSwift,我們可以自己寫一個簡單的 RxSwift,幫助自己真正理解其實(shí)現(xiàn)原理,從而更好地使用 RxSwift 進(jìn)行開發(fā)。
基本原理
RxSwift 是觀察者模式的拓展版,但歸根結(jié)底還是觀察者模式。用戶輸入、點(diǎn)擊事件、定時器、網(wǎng)絡(luò)請求等都可以當(dāng)成 Observable(被觀察者),Observer(觀察者)總會在 Observable 處注冊一個訂閱,當(dāng)事件發(fā)生時,Observable 找到所有的訂閱并通知觀察者。
觀察者模式
簡單介紹下觀察者模式,已經(jīng)熟悉的可以跳過這一段。
當(dāng)一個對象的狀態(tài)發(fā)生變化時,所有依賴于它的對象都得到通知并做出反應(yīng)。比如在 MVC 中,Model 就是觀察者模式中的被觀察者(Subject),View 是觀察者模式中的觀察者(Observer),當(dāng) model 發(fā)生改變里,觸發(fā)通知監(jiān)聽它的 view 進(jìn)行更新。
我們用 Swift 寫一個簡單的觀察者:
//Observer pattern
protocol Observer {
func update(message: String)
}
class Subject {
var observers: Array<Observer> = []
func register(observer:Observer) {
self.observers.append(observer)
}
func notify(message: String) {
for observer in observers {
observer.update(message: message)
}
}
}
class Observer1: Observer {
func update(message: String) {
print("Observer1: " + message)
}
}
class Observer2: Observer {
func update(message: String) {
print("Observer2: " + message)
}
}
被觀察者 Subject 類內(nèi)部存儲了訂閱它的對象,當(dāng) Subject 有更新時,就會通知這些訂閱的 Observer。
let subject = Subject()
let observer1 = Observer1()
let observer2 = Observer2()
subject.register(observer: observer1)
subject.register(observer: observer2)
subject.notify(message: "zcj")
Observable
Observable 本質(zhì)上是一個函數(shù),接受一個訂閱函數(shù),當(dāng)有事件發(fā)生時,觸發(fā)這個訂閱函數(shù)進(jìn)行更新。
//simple 1: Observable
typealias EventHandler = (String) -> Void
func myObservable(eventHandler: EventHandler) {
eventHandler("zcj")
eventHandler("hello")
eventHandler("world")
}
let eventHandler : EventHandler = {(value) -> Void in
print(value)
}
myObservable(eventHandler: eventHandler)
上面定義了一個閉包 EventHandler,傳入一個 String 參數(shù),無返回值。實(shí)例化一個閉包對象 eventHandler,只是簡單地打印傳入的內(nèi)容。
函數(shù) myObservable,接收一個閉包,并根據(jù)需要調(diào)用這個閉包。
Observer
我們把 Observable 封裝成一個類,這樣可以很方便地把 Observer 當(dāng)做匿名對象傳進(jìn)去,以一種簡單的方式來使用,先看最終的使用方式
let observable = Observable{(observer) -> Void in
observer.next(value: "zcj")
}
let closure = {(value: String) -> Void in
print(value)
}
observable.subscribe(eventHandler: closure)
為了實(shí)現(xiàn)這個效果,首先把訂閱函數(shù)封裝進(jìn) Observer 類,增加一個 next 函數(shù),next 函數(shù)被調(diào)用時,執(zhí)行 Observer 所持有的訂閱函數(shù)。
//simple 2:Observer
class Observer {
typealias EventHandler = (String) -> Void
private let _eventHandler : EventHandler
init(eventHandler: @escaping EventHandler) {
self._eventHandler = eventHandler
}
func next(value: String) {
self._eventHandler(value)
}
}
func myObservable(handle: @escaping (String) -> Void) {
let observer = Observer(eventHandler: handle)
observer.next(value: "zcj")
}
let closure = {(value: String) -> Void in
print(value)
}
myObservable(handle: closure)
Observable 也包裝成類,通過 subscribeHandler 把 Observer 以內(nèi)在的形式創(chuàng)建
//simple 3
typealias EventHandler = (String) -> Void
typealias SubscribeHandler = (Observer) -> Void
class Observer {
private let _eventHandler : EventHandler
init(eventHandler: @escaping EventHandler) {
self._eventHandler = eventHandler
}
func next(value: String) {
self._eventHandler(value)
}
}
class Observable {
private let subscribeHandler: SubscribeHandler
public init(_ subscribeHandler: @escaping SubscribeHandler) {
self.subscribeHandler = subscribeHandler
}
public func subscribe(eventHandler: @escaping EventHandler) {
let observer = Observer(eventHandler: eventHandler)
self.subscribeHandler(observer)
}
}
let observable = Observable{(observer) -> Void in
observer.next(value: "zcj")
}
let closure = {(value: String) -> Void in
print(value)
}
observable.subscribe(eventHandler: closure)
Operator
RxSwift 中的操作符其實(shí)是一個接收源 Observable,然后加工處理后返回一個新的 Observable,我們實(shí)現(xiàn)一個簡單的 map 操作符,代碼如下:
//simple 4
typealias EventHandler = (String) -> Void
typealias SubscribeHandler = (Observer) -> Void
class Observer {
private let _eventHandler : EventHandler
init(eventHandler: @escaping EventHandler) {
self._eventHandler = eventHandler
}
func next(value: String) {
self._eventHandler(value)
}
}
class Observable {
private let subscribeHandler: SubscribeHandler
public init(_ subscribeHandler: @escaping SubscribeHandler) {
self.subscribeHandler = subscribeHandler
}
public func subscribe(eventHandler: @escaping EventHandler) {
let observer = Observer(eventHandler: eventHandler)
self.subscribeHandler(observer)
}
}
func map(source: Observable, transform: @escaping (_ value: String) -> String) -> Observable {
return Observable({ (observer) in
let closure = {(value: String) -> Void in
let transformedValue = transform(value)
observer.next(value: transformedValue)
}
source.subscribe(eventHandler: closure)
})
}
let observable = Observable{(observer) -> Void in
observer.next(value: "zcj")
}
let closure = {(value: String) -> Void in
print(value)
print(value)
print(value)
}
map(source: observable) { (value) -> String in
return "hi " + value
}.subscribe(eventHandler: closure)
在 map 內(nèi)部,根據(jù)外層傳進(jìn)來的閉包 transform 處理生成一個新的 Observable。
在新的 Observable 內(nèi)部,創(chuàng)建一個閉包將 value 轉(zhuǎn)換成 transformedValue,原始的 sourec 訂閱這個閉包,當(dāng)監(jiān)聽到外層數(shù)據(jù)傳進(jìn)來,通知內(nèi)部 observer 進(jìn)行更新。
本文 Demo:https://github.com/superzcj/RxSwiftDemo
總結(jié)
首先我們從理論上介紹了 RxSwift 基本原理,然后用 Swift 實(shí)現(xiàn)了 RxSwift 的基礎(chǔ):觀察者模式,最后分別實(shí)現(xiàn)了 Observable、Observer 和 Operator。
以上都屬于 RxSwift 的核心,我們完整實(shí)現(xiàn)一遍,相信在這個過程中,大家會對 RxSwift 有一個更深刻的認(rèn)識,同時也能更好地運(yùn)用 RxSwift 進(jìn)行開發(fā)。
下一篇我們將介紹 RxSwift 如何結(jié)合 MVVM,更好地服務(wù)我們的業(yè)務(wù)開發(fā)。