前言
在使用ReactiveCocoa的時(shí)候,對(duì)于型號(hào)在主線程上的處理經(jīng)常會(huì)用到observeOn(UIScheduler())
或者observeOn(QueueScheduler.main)
。從字面意思來(lái)講UI線程和主線程應(yīng)該是同一個(gè)線程,那么這兩個(gè)用法有什么區(qū)別呢?
源碼
要想知道內(nèi)部的區(qū)別,需要從源碼入手。
下面是ReactiveCocoa5.0.0-alpha.3的相關(guān)代碼。
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.
盡可能的在主隊(duì)列上執(zhí)行所有工作的調(diào)度器。
如果調(diào)度程序在操作時(shí)已在主隊(duì)列上運(yùn)行,則可以同步運(yùn)行。 但是,操作之間的順序?qū)⑹冀K保留。
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
}
······
代碼中可以看到,在初始化方法中調(diào)用了自己的私有的靜態(tài)函數(shù),在主線程上設(shè)置了一對(duì)鍵值。
而從注釋可以看出,init方式是用來(lái)確保UIScheduler
已經(jīng)正確設(shè)置為主線程,而且只會(huì)在應(yīng)用周期里面調(diào)用一次。
QueueScheduler的描述:
A scheduler backed by a serial GCD queue.
由串行GCD支持的調(diào)度器
簡(jiǎn)單明了。
QueueScheduler.main的相關(guān)代碼:
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
}
}
簡(jiǎn)單來(lái)說(shuō),QueueScheduler.main
其實(shí)就是QueueScheduler
在主線程上的單例模式,而下面note這句話也最終解釋了UIScheduler
與QueueScheduler.main
的區(qū)別的區(qū)別。
區(qū)別
UIScheduler
與QueueScheduler.main
背后都是通過(guò)GCD調(diào)用的主線程,區(qū)別是QueueScheduler.main
只能在主線程上異步執(zhí)行,而調(diào)用UIScheduler
時(shí),如果本身已經(jīng)在主線程上了,那么就可以可以在主線程上同步執(zhí)行,