美文网首页iOS开发并发处理iOS学习开发
UIScheduler与QueueScheduler.main的

UIScheduler与QueueScheduler.main的

作者: 嘻嘻zhy | 来源:发表于2016-11-29 23:42 被阅读157次

    前言

    在使用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<UInt8>()
        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的

        本文链接:https://www.haomeiwen.com/subject/ispzpttx.html