DispatchQueue中的目标参数

时间:2016-11-16 14:25:12

标签: swift queue dispatch

在Swift 3中,创建了一个DispatchQueue实例:

DispatchQueue(label: String,
              qos: DispatchQoS,
              attributes: DispatchQueue.Attributes,
              autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency, 
              target: DispatchQueue?)

我看到StackOverFlow中的示例代码,它可以是nil,.global()或.main,这个target参数的含义是什么?

我猜.main表示队列将在主线程上运行,但对于.nil或.global()是什么?

4 个答案:

答案 0 :(得分:9)

没有Swift的文档,所以我回到了GCD的旧文档。我发现的最接近函数dispatch_set_target_queue

  

对象的目标队列负责处理对象。目标队列确定调用对象终结器的队列。此外,修改某些对象的目标队列会改变它们的行为:

     

派遣队列:

     

调度队列的优先级从其目标队列继承。使用dispatch_get_global_queue函数获取所需优先级的合适目标队列。

     

如果将块提交到串行队列,并且串行队列的目标队列是不同的串行队列,则不会与提交到目标队列的块或具有相同目标队列的任何其他队列同时调用该块。 / p>

看起来target队列做了两件事:

  1. 为新队列提供优先级
  2. 执行队列中所有对象的终结器(deinit
  3. 在行之间读取,队列和目标队列之间存在一些同步。我目前没有Xcode,所以我无法测试。

答案 1 :(得分:3)

目标由苹果解释为:

"调度队列的优先级从其目标队列继承。使用dispatch_get_global_queue函数获取所需优先级的合适目标队列。 如果将块提交到串行队列,并且串行队列的目标队列是不同的串行队列,则不会与提交到目标队列的块或具有相同目标队列的任何其他队列同时调用该块。"

https://developer.apple.com/reference/dispatch/1452989-dispatch_set_target_queue

<强> 1 .main将在主线程上运行。主线程主要用于UI工作,因此在使用此线程进行与UI无关的工作时应谨慎,因为它可能会使UI挂起或显示无响应。此队列具有最高优先级。

<强> 2 .global主要用于与UI无关的其他工作。并在线程可用时调度块。全局队列有三个优先级Low, Default & High。此队列具有第二高优先级,具有3种不同类型。

第3 nil是最低优先级,并且低于任何全局队列。它没有优先权,只需要完成。

<强>摘要

.main作为UI工作的目标

.global作为其他需要尽快完成的工作的目标

没有作为工作的目标,只需要在某个时刻完成(你没有打扰)

答案 2 :(得分:1)

TLDR:指定目标队列将为您的队列提供最低的QoS,并将所有块重定向到目标队列,同时保留队列的语义。

例如,假设队列A是并发的,队列B是针对A的串行的:

// serial A -> targets concurrent B

// concurrent queue A
let a = DispatchQueue(label: "A", attributes: .concurrent)

// serial queue B targeting concurrent queue A
let b = DispatchQueue(label: "B", target: a)

// next two blocks will be executed concurrently on A
a.async {
    print("1")
}
a.async {
    print("2")
}

// next two blocks will be executed serially on A
b.async {
    print("3")
}
b.async {
    print("4")
}

https://developer.apple.com/documentation/dispatch/dispatchobject/1452989-settarget

将所有块从当前调度队列重定向到指定的目标队列。使用目标队列将工作从几个不同的队列重定向到单个队列。您可以这样做以最大程度地减少应用程序使用的线程总数,同时仍保留所需的执行语义。如果系统具有目标队列,则系统不会将线程分配给调度队列,除非该目标队列是全局并发队列。

目标队列定义了块在何处运行,但不会更改当前队列的语义。即使基础目标队列是并发的,提交到串行队列的块仍然按顺序执行。另外,您不能在没有并发的地方创建并发。如果一个队列及其目标队列都是串行的,则将块提交到两个队列不会导致这些块同时运行。这些块仍按目标队列接收它们的顺序连续运行。

调度队列从其目标队列继承了最低服务质量级别。

答案 3 :(得分:0)

目标用于设置目标队列层次结构。它不用于QoS。它用于控制线程数和目标队列层次结构。

QoS和您要创建的队列的特征将保持不变。但是通过这样做,性能将有所不同。有关更多信息,请参阅WWDC视频。