理解 RxSwift:爲何要使用 RxSwift(一)git
理解 RxSwift:實現原理(二)github
RxSwift 內部是如何運行的,Observable 與 Observer 之間存在什麼關係,Operator 又是如何實現的,若是想完全弄清楚 RxSwift,咱們能夠本身寫一個簡單的 RxSwift,幫助本身真正理解其實現原理,從而更好地使用 RxSwift 進行開發。api
RxSwift 是觀察者模式的拓展版,但歸根結底仍是觀察者模式。用戶輸入、點擊事件、定時器、網絡請求等均可以當成 Observable(被觀察者),Observer(觀察者)總會在 Observable 處註冊一個訂閱,當事件發生時,Observable 找到全部的訂閱並通知觀察者。bash
簡單介紹下觀察者模式,已經熟悉的能夠跳過這一段。網絡
當一個對象的狀態發生變化時,全部依賴於它的對象都獲得通知並作出反應。好比在 MVC 中,Model 就是觀察者模式中的被觀察者(Subject),View 是觀察者模式中的觀察者(Observer),當 model 發生改變裏,觸發通知監聽它的 view 進行更新。閉包
咱們用 Swift 寫一個簡單的觀察者:app
//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 類內部存儲了訂閱它的對象,當 Subject 有更新時,就會通知這些訂閱的 Observer。函數
let subject = Subject()
let observer1 = Observer1()
let observer2 = Observer2()
subject.register(observer: observer1)
subject.register(observer: observer2)
subject.notify(message: "zcj")
複製代碼
Observable 本質上是一個函數,接受一個訂閱函數,當有事件發生時,觸發這個訂閱函數進行更新。post
//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 參數,無返回值。實例化一個閉包對象 eventHandler,只是簡單地打印傳入的內容。ui
函數 myObservable,接收一個閉包,並根據須要調用這個閉包。
咱們把 Observable 封裝成一個類,這樣能夠很方便地把 Observer 當作匿名對象傳進去,以一種簡單的方式來使用,先看最終的使用方式
let observable = Observable{(observer) -> Void in
observer.next(value: "zcj")
}
let closure = {(value: String) -> Void in
print(value)
}
observable.subscribe(eventHandler: closure)
複製代碼
爲了實現這個效果,首先把訂閱函數封裝進 Observer 類,增長一個 next 函數,next 函數被調用時,執行 Observer 所持有的訂閱函數。
//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 之內在的形式建立
//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)
複製代碼
RxSwift 中的操做符實際上是一個接收源 Observable,而後加工處理後返回一個新的 Observable,咱們實現一個簡單的 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 內部,根據外層傳進來的閉包 transform 處理生成一個新的 Observable。
在新的 Observable 內部,建立一個閉包將 value 轉換成 transformedValue,原始的 sourec 訂閱這個閉包,當監聽到外層數據傳進來,通知內部 observer 進行更新。
本文 Demo:github.com/superzcj/Rx…
首先咱們從理論上介紹了 RxSwift 基本原理,而後用 Swift 實現了 RxSwift 的基礎:觀察者模式,最後分別實現了 Observable、Observer 和 Operator。
以上都屬於 RxSwift 的核心,咱們完整實現一遍,相信在這個過程當中,你們會對 RxSwift 有一個更深入的認識,同時也能更好地運用 RxSwift 進行開發。
下一篇咱們將介紹 RxSwift 如何結合 MVVM,更好地服務咱們的業務開發。