UIScheduler与QueueScheduler.main的区别

前言

在使用ReactiveCocoa的时候,对于型号在主线程上的处理经常会用到observeOn(UIScheduler())或者observeOn(QueueScheduler.main)。从字面意思来讲UI线程和主线程应该是同一个线程,那么这两个用法有什么区别呢?


源码

要想知道内部的区别,需要从源码入手。
下面是ReactiveCocoa5.0.0-alpha.3的相关代码。

UISchdule的描述:

/// A scheduler that performs all work on the main queue, as soon as possible.
///
/// If the caller is already running on the main queue when an action is
/// scheduled, it may be run synchronously. However, ordering between actions
/// will always be preserved.

尽可能的在主队列上执行所有工作的调度器。
如果调度程序在操作时已在主队列上运行,则可以同步运行。 但是,操作之间的顺序将始终保留。

UISchdule的代码:

public final class UIScheduler: SchedulerProtocol {
    private static let dispatchSpecificKey = DispatchSpecificKey()
    private static let dispatchSpecificValue = UInt8.max
    private static var __once: () = {
            DispatchQueue.main.setSpecific(key: UIScheduler.dispatchSpecificKey,
                                           value: dispatchSpecificValue)
    }()
······
    public init() {
        /// This call is to ensure the main queue has been setup appropriately
        /// for `UIScheduler`. It is only called once during the application
        /// lifetime, since Swift has a `dispatch_once` like mechanism to
        /// lazily initialize global variables and static variables.
        _ = UIScheduler.__once
    }
······

代码中可以看到,在初始化方法中调用了自己的私有的静态函数,在主线程上设置了一对键值。
而从注释可以看出,init方式是用来确保UIScheduler已经正确设置为主线程,而且只会在应用周期里面调用一次。


QueueScheduler的描述:

A scheduler backed by a serial GCD queue.
由串行GCD支持的调度器

简单明了。

QueueScheduler.main的相关代码:

public final class QueueScheduler: DateSchedulerProtocol {
    /// A singleton `QueueScheduler` that always targets the main thread's GCD
    /// queue.
    ///
    /// - note: Unlike `UIScheduler`, this scheduler supports scheduling for a
    ///         future date, and will always schedule asynchronously (even if 
    ///         already running on the main thread).
    public static let main = QueueScheduler(internalQueue: DispatchQueue.main)
    public let queue: DispatchQueue
    
    internal init(internalQueue: DispatchQueue) {
        queue = internalQueue
    }
}

简单来说,QueueScheduler.main其实就是QueueScheduler在主线程上的单例模式,而下面note这句话也最终解释了UISchedulerQueueScheduler.main的区别的区别。

区别

UISchedulerQueueScheduler.main背后都是通过GCD调用的主线程,区别是QueueScheduler.main只能在主线程上异步执行,而调用UIScheduler时,如果本身已经在主线程上了,那么就可以可以在主线程上同步执行,

你可能感兴趣的:(UIScheduler与QueueScheduler.main的区别)