Swift 3 中 DispatchQueue 上的 AutoreleaseFrequency

AutoreleaseFrequency on DispatchQueue in Swift 3

在 Xcode 8 beta 5 中,DispatchQueue 的初始值设定项已更改为接受 qos(服务质量)、属性和自动释放频率的单独参数。虽然我在转换我的代码以使用新的初始化程序时没有任何问题,但我不确定某些属性的含义,尤其是自动释放频率。

例如,在 Xcode 8 beta 3 和 Swift 3 中,我可以这样创建一个序列 DispatchQueue

let serialQueue = DispatchQueue(label: "Concurrent Map", attributes: [.serial, .qosBackground], target: nil)

在 Xcode 8 beta 5 和 Swift 3 中:

let serialQueue = DispatchQueue(label: "Concurrent Map", qos: .background, attributes: [], autoreleaseFrequency: .inherit, target: nil)

我的问题是:

我找不到这些新属性的任何官方文档(可能正在处理),但鉴于现有的 GCD 文档,并阅读其中的字里行间,很容易凭直觉理解这里的意图。

In the new DispatchQueue.Attributes, .serial is no longer a member. Does this mean that the absence of .concurrent creates a serial queue. An initial test I did in Swift Playgrounds seems to confirm this. Can anyone else confirm?

是的。队列是串行的或并发的。您创建的大多数队列都是串行的,因此如果您不想要默认行为,只需将它们设置为并发即可。

I see that DispatchQueue.AutoreleaseFrequency is a new type with .inherit, .never, and .workItem. What do these mean? I did some research on GCD and autoreleasing but I'm not very familiar with the concept of autorelease pools.

以前,DispatchQueues 会在未指定的时间(当线程变为非活动状态时)弹出它们的自动释放池。实际上,这意味着您要么为提交的每个调度项创建一个自动释放池,要么您的自动释放对象将停留不可预测的时间。

非确定性并不是一件好事(特别是在并发库中!),因此它们现在允许您指定三种行为之一:

.inherit:不确定,可能是以前的默认行为

.workItem:为每个执行的项目创建并清空自动释放池

.never: GCD 不会为你管理自动释放池

在所有这些中,您可能只想使用 .workItem,因为它会在项目完成时清理您的临时对象。其他选项可能是针对依赖于旧行为的错误代码,或者是针对那些真正想要自己管理这些东西的少数用户。


实际上,仔细考虑一下,如果您提交的工作项仅 Swift(它们不调用任何 Objective-C 代码),那么 .never 是可能是安全和正确的。鉴于 any/all Swift 标准库 类 可能会调用一些 Objective-C 代码,您可能希望将其限制为完全驻留在您自己的 Swift 中的计算代码。

我找到了 Mark "subjective" 给出的答案,正如他所说,文档中还没有官方文档。但是,您可以在代码中找到官方文档,因此我给出了我认为应该是正确的答案,因为它完全基于代码文档中的内容而不是意见。这是:

DISPATCH_AUTORELEASE_FREQUENCY_INHERIT 具有此自动释放频率的调度队列从其目标队列继承行为。这是手动创建队列的默认行为。

DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM 具有此自动释放频率的调度队列围绕异步提交给它的每个块的执行推送和弹出自动释放池。

DISPATCH_AUTORELEASE_FREQUENCY_NEVER 具有这种自动释放频率的调度队列永远不会围绕异步提交给它的块的执行设置单独的自动释放池。这是全局并发队列的行为。