理解 RxSwift:實(shí)現(xiàn)原理(二)

理解 RxSwift:為什么要使用 RxSwift(一)

理解 RxSwift:實(shí)現(xiàn)原理(二)

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ā)。

參考資料

rxjs原理解析之自己造一個

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容