64

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

并遇到了 QoS 类User-interactive的定义。它在那里提到这应该在主线程上运行。所以,我的问题是

DispatchQueue.global(qos: .userInteractive).async{} 

DispatchQueue.main.async{}

谢谢!!

4

5 回答 5

33

此处描述了“服务质量”定义:

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

看起来“主”线程将具有“用户交互”的 QoS 类。然而,仅仅因为一个线程是使用“用户交互”的 QoS 创建的,并不意味着它是“主”线程。

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

通常,主线程被认为是应该执行所有与视图相关的访问的特殊线程。如果某些事情会消耗​​大量时间,例如调用 Web 服务、压缩文件等,您将需要在单独的队列中运行代码,并且当该过程完成时,返回到您更新用户界面的主队列。

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

于 2017-08-28T06:35:37.917 回答
14

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

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

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

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

于 2018-04-04T19:21:38.523 回答
10

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

苹果自己的示例代码和注释让事情变得非常清楚:

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

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

于 2018-04-05T13:18:00.400 回答
4

DispatchQueue.global(qos: .userInteractive).async{}当您想在用户与您的应用程序交互时在后台非常快速地做某事时,您可以使用它。这很少使用,因为它必须发生得如此之快,您可能可以直接在主队列中进行。

您可以查看这个讲座,其中非常清楚地解释了这个问题。

于 2018-04-04T18:57:35.713 回答
0

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

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

与使用 dispatch_queue_create() 分配的一个或多个主队列不同,全局并发队列在线程可用时立即调度阻塞(“非 FIFO”完成顺序)。全局并发队列代表三个优先级:

   •   DISPATCH_QUEUE_PRIORITY_HIGH
   •   DISPATCH_QUEUE_PRIORITY_DEFAULT
   •   DISPATCH_QUEUE_PRIORITY_LOW

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

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

于 2018-04-06T04:40:16.913 回答