RxSwiftのスケジューラ

4087 ワード

ReactiveCocoaに比べてRxの大きな利点は,より豊富な同時モデルである.同時といえば,マルチスレッドを抽出せざるを得ない.RxSwiftでは、スレッドに対応する概念がスケジューラです.本稿では、コンカレントスケジューラ、シリアルスケジューラ、RxSwift内蔵スケジューラ、カスタムスケジューラなど、スケジューラについて説明します.
記事のアドレス:https://www.cnblogs.com/xjshi/p/9759551.html
スケジューラは動作を実行するメカニズムを抽象化し,スケジューラが元のスレッドに対応しているとあまり正確に考えられない.observeOnsubscribeOnの2つのオペレータは、スケジューラと組み合わせて使用できます.
異なるスケジューラで作業を実行したい場合は、observeOn(scheduler)オペレータを使用します.observerOnが明示的に指定されていない場合、動作は要素を生成するスケジューラで実行されます.
下はobserveOnを使用した例です.
sequence1
  .observeOn(backgroundScheduler)
  .map { n in
      print("This is performed on the background scheduler")
  }
  .observeOn(MainScheduler.instance)
  .map { n in
      print("This is performed on the main scheduler")
  }

シーケンスを指定したスケジューラ上で生成(subscribeメソッド)およびdisposeしたい場合は、subscribeOn(scheduler)を使用します.subscribeOnが明示的に指定されていない場合、subscribe(onNext:)またはsubscribeが呼び出された同じスケジューラでsubscribe閉パケット(Observable.createに渡される閉パケット)が呼び出される.subscribeOnが明示的に指定されていない場合、disposeメソッドはdisposingを起動する同じスケジューラで呼び出される.
簡単に言えば、明示的な選択スケジューラがない場合、これらのメソッドは現在のスケジューラで呼び出されます.

シリアルスケジューラvsコンカレントスケジューラ


スケジューラは任意のものであり、すべての変換シーケンスの操作サブには追加の保証が必要であるため、どのスケジューラを作成するかが重要です.
ここでの保証は、すべてのシーケンス(Observable)について、そのスレッド上で要素が生成されても、シーケンスがobserver.ron(.next(nextElement))を介して観察者に1つの要素を送信する場合、シーケンスはobserver.onメソッドの実行が終了する前に次の要素を送信できないことを意味する..nextメソッドが完了しない場合、シーケンスは、.completedまたは.errorのような終了コマンドを送信することもできない.
この部分はRxSwiftの入門文で紹介されています.
スケジューラが同時である場合、RxのobserveOnおよびsubscribeOnオペレータは、すべてが正常であることを保証します.
Rxを使用してシリアルスケジューラであることを証明できる場合は、追加の最適化を実行できます.
シリアルスケジューラの場合、observeOnは単純なdispatch_async呼び出しに最適化される.

カスタムスケジューラ


現在のスケジューラに加えて、自分のスケジューラを実現することもできます.
すぐに作業を実行するスケジューラを説明したい場合は、ImmediateSchedulerプロトコルを実装できます.
public protocol ImmediateScheduler {
    func schedule(state: StateType, action: (/*ImmediateScheduler,*/ StateType) -> RxResult) -> RxResult
}

イベント・ベースの操作をサポートしたい場合は、Schedulerプロトコルを実装できます.
public protocol Scheduler: ImmediateScheduler {
    associatedtype TimeInterval
    associatedtype Time

    var now : Time {
        get
    }

    func scheduleRelative(state: StateType, dueTime: TimeInterval, action: (StateType) -> RxResult) -> RxResult
}

サイクル実行の能力を持ちたい場合は、PeriodicSchedulerプロトコルを実装することでRxに通知することができます.
public protocol PeriodicScheduler : Scheduler {
    func schedulePeriodic(state: StateType, startAfter: TimeInterval, period: TimeInterval, action: (StateType) -> StateType) -> RxResult
}

内蔵スケジューラ


上記では、Rxはすべてのタイプのスケジューラを使用できますが、Rxがスケジューラがシリアルであることを証明できれば、追加の最適化が実行されます.
  • CurrentThreadScheduler:現在動作中のスケジューラを表すシリアルスケジューラです.
  • MainScheduler:プライマリ・スレッドで実行する必要がある作業を抽象化し、もちろんシリアル・スケジューラでもあります.
  • SerialDispatchQueueScheduler:シリアル・スケジューラです.抽象的にはdispatch_queue_tで実行する必要があります.これにより、リアルタイムで同時スケジューリング・キュー(concurrent dispatch queue)が転送され、シリアル・キューに変換されます.メインスケジューラもSerialDispatchQueueSchedulerの一例です.
  • C o n c u r r r e ntDispatchQueueScheduler:dispatch_queue_tで実行する必要がある抽象的な作業を同時にスケジューラです.このスケジューラは、バックグラウンドで実行するタスクがある場合に使用します.
  • OperationQueueScheduler:抽象的にNSOperationQueueで実行する必要がある作業.バックグラウンドで多数の作業を行う必要があり、maxConcurrentOpeartionCountを使用して同時処理を調整したい場合に適しています.

  • 本明細書の部分は、Rxとの対照を表す.
    本文中の表示
    Rxでの表示
    スケジューラ
    scheduler
    シリアルスケジューラ
    serial scheduler
    コンカレントスケジューラ
    concurrent scheduler