Schedulers
- 串行与并发调度程序
- 自定义调度程序
- 内置调度程序
Schedulers抽象出执行工作的机制。
执行工作的机制包括当前线程,调度队列(dispatch queues),操作队列(operation queues),新线程,线程池和运行循环。
有两个主要的操作符使用Schedulers,observeOn和subscribeOn。
如果要在不同的Schedulers上执行工作,只需使用observeOn(scheduler)操作符。
通常使用observeOn多于subscribeOn。
如果observeOn未明确指定,则将在生成元素的任何线程/scheduler执行工作。
使用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")
}
如果要在特定scheduler上启动序列生成元素(subscribe方法)并调用dispose,请使用subscribeOn(scheduler)。
如果subscribeOn未明确指定,则将在调用subscribe(onNext:)或调用subscribe的同一线程/scheduler上调用subscribe闭包(传递给Observable.create的闭包)。
如果subscribeOn未明确指定,dispose方法则将在启动disposing的同一线程/scheduler上调用。
简而言之,如果没有选择显式调度程序,那么将在当前线程/scheduler上调用这些方法。
串行与并发Schedulers
由于Schedulers确实可以是任何东西,并且所有转换序列的操作符都需要保留额外的隐式保证,因此创建的是哪种Schedulers非常重要。
如果调度程序是并发的,Rx的observeOn和subscribeOn操作符将确保一切正常。
如果使用Rx可以证明某些scheduler是串行的,将可以执行一些其他优化。
到目前为止,只对调度队列调度程序执行那些优化。
在串行scheduler的情况下,observeOn优化只是一个简单的dispatch_async调用。
自定义Schedulers
除了已有的Schedulers,还可以编写自己的Schedulers。
如果只想描述谁需要立即执行工作,可以通过实现ImmediateScheduler协议来创建自己的Schedulers。
public protocol ImmediateScheduler {
func schedule<StateType>(state: StateType, action: (/*ImmediateScheduler,*/ StateType) -> RxResult<Disposable>) -> RxResult<Disposable>
}
如果要创建支持基于时间操作的新Schedulers,则需要实现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>
}
如果Schedulers仅具有定期调度功能,则可以通过实现PeriodicScheduler协议来通知Rx :
public protocol PeriodicScheduler : Scheduler {
func schedulePeriodic<StateType>(state: StateType, startAfter: TimeInterval, period: TimeInterval, action: (StateType) -> StateType) -> RxResult<Disposable>
}
这种情况下如果Schedulers不支持PeriodicScheduling功能,Rx将显式模拟定期调度。
内置Schedulers
Rx可以使用所有类型的schedulers,但如果具有scheduler是串行的证据,还可以执行一些额外的优化。
这些是当前支持的schedulers:
CurrentThreadScheduler(串行scheduler)
当前线程的工作单元。这是生成元素的操作符的默认scheduler。
该scheduler有时也称为"trampoline scheduler"。
如果CurrentThreadScheduler.instance.schedule(state) { }在某个线程上第一次调用,则将立即执行调度的操作,并将创建一个隐藏的队列,其中所有递归调度的操作将暂时排入队列。
如果在调用堆栈上的某个父框架已运行CurrentThreadScheduler.instance.schedule(state) { },则当前正在运行的操作和所有先前排队的操作已完成执行时,计划的操作将被排入队队列并执行。
MainScheduler(串行scheduler)
需要在MainThread执行的工作。如果schedule从主线程调用方法,它将立即执行操作而无需调度。
此调度程序通常用于执行UI工作。
SerialDispatchQueueScheduler(串行scheduler)
需要把工作抽象到特定的dispatch_queue_t执行。它将确保即使通过并发scheduler,它也会转换为串行队列。
串行scheduler使用observeOn启用某些优化。
main scheduler是一个SerialDispatchQueueScheduler实例。
ConcurrentDispatchQueueScheduler(并发scheduler)
需要把工作抽象到特定的dispatch_queue_t执行。也可以通过一个串行调度队列,不应该导致任何问题。
当需要在后台执行某些工作时,此scheduler适用。
OperationQueueScheduler(并发scheduler)
需要把工作抽象到特定的NSOperationQueue执行。
此scheduler适用于需要在后台执行大量工作并且希望使用maxConcurrentOperationCount处理并发数量。