是DispatchQueue.global(qos:.userInteractive).async与DispatchQueue.main.async相同

时间:2017-08-28 05:58:16

标签: ios swift

我正在阅读教程: https://www.raywenderlich.com/148513/grand-central-dispatch-tutorial-swift-3-part-1

并且遇到了QoS类用户交互式的定义。 它在那里提到它应该在主线程上运行。 那么,我的问题是

之间的区别是什么
DispatchQueue.global(qos: .userInteractive).async{} 

DispatchQueue.main.async{}

谢谢!

5 个答案:

答案 0 :(得分:16)

"服务质量"定义在这里描述:

https://developer.apple.com/library/content/documentation/Performance/Conceptual/EnergyGuide-iOS/PrioritizeWorkWithQoS.html

它看起来像"主要"线程将具有"用户交互式"的QoS等级。但是,仅仅因为创建了一个具有" User-interactive"的QoS的线程,并不意味着它是" main"线程。

您可以在Xcode调试器中观察到这一点。在异步块中放置一个断点,然后查看Debug Navigator活动线程面板。从主线程调用DispatchQueue.global(qos: .userInteractive).async{}时,它显示的名称与主线程不同。

通常,主线程被视为应执行所有与视图相关的访问的特殊线程。如果某些东西会消耗很长时间,例如如果要调用Web服务,压缩文件等,则需要在单独的队列中运行代码,当进程完成时,返回到更新用户界面的主队列。

另请注意,在iOS 11中使用Xcode 9时,从非主线程访问用户界面对象时会发出警告。

答案 1 :(得分:5)

任何说.userInitiated全局队列是主线程的人都错了。它是一个非常高优先级的后台队列,但它是一个后台队列(与主线程不同,它是并发的)。

Apple自己的sample code and comments让事情变得非常明确:

// This handler gets called on the main thread; dispatch to a background queue for processing.
DispatchQueue.global(qos: .userInitiated).async {

这证明了Apple认为.userInitiated全局队列是“后台队列”而不是“主线程”。

答案 2 :(得分:2)

这些不一样。它们意味着不同的东西,你应该使用你的意思。主队列是userInteractive,但并非每个userInteractive队列都是主队列。 Apple在Building Responsive and Efficient Apps with GCD中对此进行了详细讨论。

在userInteractive级别运行多个队列是有效的。如果您需要同时使用多个内核来执行所需的计算以保持平滑的用户交互(通常是某种动画),这是合适的。这是非常罕见的,并且应该小心,但是如果你需要在主线程上计算某些东西,同时还要在另一个核心上计算某些东西以便跟上用户的行为,那就是它的用途。

但是只能有一个主队列。它恰好是userInteractive,但这不是重点。大多数UIKit都不是线程安全的,它只对主队列上的那些类有效,而不仅仅是访问任何userInteractive队列。

队列优先级最初看起来更复杂。它们可以从队列传播到队列,使得“低优先级”队列可以暂时具有高优先级状态。 Apple调整了它如何工作以使整个系统更具响应性。这就是为什么总是表达你的意思而不是依赖关于事情如何在幕后工作的假设是如此重要的原因。即使您的测试显示两个队列始终相同,也不足以知道它们在所有设备或操作系统的未来版本中都是相同的。

答案 3 :(得分:1)

当您想要在用户与您的应用互动时在后台快速执行某些操作时,可以使用DispatchQueue.global(qos: .userInteractive).async{}。这很少使用,因为它必须如此快速地发生,你可能可以直接在主队列中进行。

您可以查看lecture这个问题的清楚解释。

答案 4 :(得分:0)

主队列确实像你说的那样在主线程上运行。

全局队列是并发队列,并且来自dispatch_get_global_queue的主页:

与使用dispatch_queue_create()分配的主队列或队列不同,一旦线程可用,全局并发队列就会调度块(“非FIFO”完成顺序)。全局并发队列代表三个优先级带:

   •   DISPATCH_QUEUE_PRIORITY_HIGH
   •   DISPATCH_QUEUE_PRIORITY_DEFAULT
   •   DISPATCH_QUEUE_PRIORITY_LOW

提交到高优先级全局队列的块将在提交到默认或低优先级全局队列的块之前被调用。只有在默认或高优先级队列中没有待处理的块时,才会调用提交到低优先级全局队列的块。

因此,它们是在后台线程上运行的队列,当它们可用时。它们是“非FIFO”,因此无法保证订购。