DispatchQueue中的目标参数

pzs*_*602 10 queue dispatch swift

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

DispatchQueue(label: String,
              qos: DispatchQoS,
              attributes: DispatchQueue.Attributes,
              autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency, 
              target: DispatchQueue?)
Run Code Online (Sandbox Code Playgroud)

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

我猜.main意味着队列将在主线程上运行,但是.nil或.global()是什么?

che*_*bur 12

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")
}
Run Code Online (Sandbox Code Playgroud)

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

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

目标队列定义块运行的位置,但它不会更改当前队列的语义。即使底层目标队列是并发的,提交到串行队列的块仍然串行执行。此外,您无法在不存在并发的情况下创建并发。如果队列及其目标队列都是串行的,则向两个队列提交块不会导致这些块同时运行。这些块仍然按照目标队列接收它们的顺序串行运行。

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


Cod*_*ent 9

Swift没有文档,所以我回到了GCD的旧文档.我发现的最接近的功能是dispatch_set_target_queue:

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

派遣队列:

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

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

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

  1. 为您的新队列提供priorty
  2. 执行deinit队列中所有对象的终结器()

在行之间读取,队列和目标队列之间存在一些同步.我目前没有Xcode,所以我无法测试.

  • 1. 为您的新队列提供优先级。-> 那么 qos 属性有什么作用。 (2认同)

tor*_*ers 7

苹果对该目标的解释是:

\n\n

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

\n\n

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

\n\n

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

\n\n

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

\n\n

3. \nnil 是最低优先级,低于任何全局队列。它没有优先级,只是需要完成。

\n\n

概括

\n\n

.main 作为 UI 工作的目标

\n\n

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

\n\n

nil 作为只需要在某个时候完成的工作的目标(你不介意什么时候)

\n

  • 仍然令人困惑。对象要调用的“终结器”是什么?又和Qos有什么关系呢? (3认同)