首页 技术 正文
技术 2022年11月11日
0 收藏 474 点赞 2,230 浏览 2484 个字

与 ReactiveCocoa 相比,Rx 的一大优势就是更丰富的并发模型。提到并发,就不得不提多线程。在 RxSwift 中,与线程对应的概念就是调度器,本文就调度器做些介绍,包括并发调度器、串行调度器、RxSwift 内置的调度器,及自定义调度器。

文章地址:https://www.cnblogs.com/xjshi/p/9759551.html

调度器抽象出了执行工作的机制,可以不怎么准确的认为调度器对应原本的线程。

observeOnsubscribeOn 这两个操作符可以与调度器配合使用。

如果你想在一个不同的调度器执行工作,那就使用 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,那么将在启动 disposing 的同一调度器上调用 dispose 方法。

简而言之,如果没有显式的选择调度器,那么将在当前调度器上调用这些方法。

串行调度器 vs 并发调度器

由于调度器可以是任何东西,并且所有转换序列的操作副都需要有额外的保证,因此你创建的是哪种调度器非常重要。

这里的保证是指,对所有的序列(Observable)而言,不论它在那个线程上产生元素,如果序列通过 observer.ron(.next(nextElement)) 将一个元素发送给观察者,那么序列在 observer.on 方法执行结束前不能发送下一个元素。

如果 .next 方法没有执行完成,序列也不能发送终止命令,如 .completed.error

这部分内容在RxSwift 入门一文中介绍过。

如果调度器是并发的,Rx 的 observeOnsubscribeOn 操作符将确保一切正常。

如果你使用Rx可以证明是串行的调度器,它能够执行额外的优化。

在串行调度器的情况下, observeOn 被优化为一个简单的 dispatch_async 调用。

自定义调度器

除了当前的调度器,你也可以实现自己的调度器。

如果你想要描述立即执行工作的调度器,可以实现 ImmediateScheduler 协议。

public protocol ImmediateScheduler {
func schedule<StateType>(state: StateType, action: (/*ImmediateScheduler,*/ StateType) -> RxResult<Disposable>) -> RxResult<Disposable>
}

如果你想要支持基于事件的操作,那么你可以实现 Scheduler 协议:

public protocol Scheduler: ImmediateScheduler {
associatedtype TimeInterval
associatedtype Time var now : Time {
get
} func scheduleRelative<StateType>(state: StateType, dueTime: TimeInterval, action: (StateType) -> RxResult<Disposable>) -> RxResult<Disposable>
}

如果你想有周期执行的能力,你可以通过实现 PeriodicScheduler 协议来通知 Rx。

public protocol PeriodicScheduler : Scheduler {
func schedulePeriodic<StateType>(state: StateType, startAfter: TimeInterval, period: TimeInterval, action: (StateType) -> StateType) -> RxResult<Disposable>
}

内置的调度器

上边我们提到 Rx 可以使用所有类型的调度器,但如果 Rx 可以证明调度器是串行的,那么会执行额外的优化

  1. CurrentThreadScheduler:它是一个串行调度器,表示当前执行工作的调度器。
  2. MainScheduler:抽象了需要在主线程执行的工作,当然也是一个串行调度器。
  3. SerialDispatchQueueScheduler:是一个串行调度器,抽象需要在一个 dispatch_queue_t 上执行的工作,它将确保即时传递并发调度队列(concurrent dispatch queue),它也会转换为串行队列。主调度器 也是 SerialDispatchQueueScheduler 的一个示例。
  4. ConcurrentDispatchQueueScheduler:是一个并发调度器,抽象需要在一个 dispatch_queue_t 上执行的工作。当一些任务需要在后台执行时,使用这个调度器。
  5. OperationQueueScheduler:抽象需要在 NSOperationQueue 上执行的工作。适用于需要在后台执行大量工作,并希望通过使用 maxConcurrentOpeartionCount 来调整并发处理的情况。

本文中的部分表示 与 Rx 中的对照:

本文中的表示 Rx中的表示
调度器 scheduler
串行调度器 serial scheduler
并发调度器 concurrent scheduler
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,101
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,577
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,425
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,197
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,832
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,915