对 Operation 和 OperationQueue QoS 关系感到困惑

Confused about Operation and OperationQueue QoS relationship

OperationQueue 文档说明 qualityOfService 属性:

This property specifies the service level applied to operation
objects added to the queue

然而,只需将下面的代码复制并粘贴到一个新的 playground 中,就可以简单地检查这不是真的。

import Foundation

let q = OperationQueue()
q.qualityOfService = .userInitiated

print("QUEUE", q.qualityOfService.rawValue)

let op = BlockOperation()
op.addExecutionBlock {
    print("OP", op.qualityOfService.rawValue)
}

q.addOperations([op], waitUntilFinished: true)

您将看到队列 QoS 级别为 25/.userInitiated 和操作 -1/.default.

这是否意味着操作 QoS 级别相对于队列提升的 .userInitiated 级别是 .default,还是 .default,尽管队列具有更高的 QoS 级别?

我实际期望的是这两个值应该相同。

PS:我需要在 Operation 中调用 Process,而 Operation 也有一个 qualityOfService 设置,应该与 queue/ops.

documentation 关于操作从队列推断 QoS(“服务质量推断和提升”部分)。

您的具体情况在此处描述为:

Any of the queue’s operations with a lower QoS are promoted to the higher QoS. Any operations with a lower QoS that are added to the queue in the future will infer the higher QoS.

但是,这并不意味着 op.qualityOfService 属性 被 OperationQueue 修改了,因为这会删除您分配给操作的 QoS。换句话说,op.qualityOfService 的值可能不代表提升的 QoS,仅代表您分配的 QoS(或 .default)。

根据swift的Operation.swiftimplementationop.queuePriority是代表队列中实际优先级的属性,毕竟应用了QoS推理和提升的复杂逻辑。您可以将它映射回 QoS,就像我刚才提到的代码中的转发方式一样

操作的 qualityOfService 指示操作本身是否需要规定特定的 QoS。但是 -1/.default 实际上意味着它将只使用队列的 QoS(以及所使用的工作线程的 QoS)。我不会非常担心操作的 QoS。你关心的是它运行的线程的QoS:

let q = OperationQueue()
q.qualityOfService = .userInitiated

print("CURRENT", Thread.current.qualityOfService.rawValue)     // CURRENT 33
print("QUEUE", q.qualityOfService.rawValue)                    // QUEUE 25

let op = BlockOperation {
    print("THREAD", Thread.current.qualityOfService.rawValue)  // THREAD 25
}

q.addOperations([op], waitUntilFinished: false)

如您所见,运行 代码线程的 QoS 正是您所期望的。


如果需要,您可以看到将操作的 QoS 更改为高于队列的 QoS 将如何影响运行它的工作线程的 QoS。因此,没有为操作指定 QoS 的后台 QoS 队列:

let q = OperationQueue()
q.qualityOfService = .background

print("CURRENT", Thread.current.qualityOfService.rawValue)    // CURRENT 33
print("QUEUE", q.qualityOfService.rawValue)                   // QUEUE 9

let op = BlockOperation()
op.addExecutionBlock {
    print("OP", op.qualityOfService.rawValue)                 // OP -1
    print("THREAD", Thread.current.qualityOfService.rawValue) // THREAD 9
}

q.addOperations([op], waitUntilFinished: false)

但如果需要,您可以为操作指定特定的 QoS,在本例中将其升级到更高的 QoS:

let q = OperationQueue()
q.qualityOfService = .background

print("CURRENT", Thread.current.qualityOfService.rawValue)    // CURRENT 33
print("QUEUE", q.qualityOfService.rawValue)                   // QUEUE 9

let op = BlockOperation()
op.qualityOfService = .userInitiated                          // change op’s QoS, and thus the worker thread to a higher QoS, too
op.addExecutionBlock {
    print("OP", op.qualityOfService.rawValue)                 // OP 25
    print("THREAD", Thread.current.qualityOfService.rawValue) // THREAD 25
}

q.addOperations([op], waitUntilFinished: false)