理解RxSwift:実現原理(二)

6325 ワード

理解RxSwift:なぜRxSwiftを使うのか(一)
理解RxSwift:実現原理(二)
RxSwift内部がどのように動いているのか、ObservableとObserverの間にどのような関係があるのか、Operatorはどのように実現しているのか、RxSwiftを徹底的に明らかにしたいなら、簡単なRxSwiftを自分で書くことができ、その実現原理を本当に理解し、RxSwiftで開発することができます.
きほんげんり
RxSwiftはオブザーバーモードの拡張版だが、結局はオブザーバーモードである.ユーザ入力、クリックイベント、タイマー、ネットワーク要求などはいずれもObservable(被観察者)とすることができ、Observer(観察者)は常にObservableにサブスクリプションを登録し、イベントが発生した場合、Observableはすべてのサブスクリプションを見つけて観察者に通知する.
オブザーバモード
観察者モードを簡単に紹介し、よく知っているのはこの部分をスキップすることができます.
1つのオブジェクトの状態が変化すると、それに依存するすべてのオブジェクトが通知され、反応します.例えばMVCでは、Modelはオブザーバーモードにおけるオブザーバー(Subject)であり、Viewはオブザーバーモードにおけるオブザーバー(Observer)であり、Modelが変更されると、それを傍受するビューをトリガーして更新する.
私たちはSwiftで簡単な観察者を書きます.
//Observer pattern
protocol Observer {
    func update(message: String)
}

class Subject {
    var observers: Array = []
    
    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
Observableは本質的に関数であり、イベントが発生した場合、このサブスクリプション関数を更新するようにトリガーされます.
//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をインスタンス化し、入力したコンテンツを簡単に印刷します.
関数myobservableは、閉パケットを受信し、必要に応じてこの閉パケットを呼び出します.
Observer
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関数を1つ増やし,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)

Operator
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:https://github.com/superzcj/RxSwiftDemo
まとめ
まずRxSwiftの基本原理を理論的に紹介し,次にSwiftを用いてRxSwiftの基礎:オブザーバーモードを実現し,最後にObservable,Observer,Operatorをそれぞれ実現した.
以上はすべてRxSwiftの核心に属して、私达は完全に1回実现して、この过程の中で、みんなはRxSwiftに対してもっと深い认识があることを信じて、同时にもっとよくRxSwiftを运用して开発することができます.
次の記事では、RxSwiftがMVVMと組み合わせて、ビジネス開発により良いサービスを提供する方法について説明します.
参考資料
rxjsの原理の解析の自分で1つ作ります