【问题标题】:AutoreleaseFrequency on DispatchQueue in Swift 3Swift 3 中 DispatchQueue 上的 AutoreleaseFrequency
【发布时间】:2016-08-10 22:13:37
【问题描述】:

在 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)

我的问题是:

  • 在新的 DispatchQueue.Attributes 中,.serial 不再是成员。这是否意味着没有 .concurrent 会创建一个串行队列。我在 Swift Playgrounds 中进行的初步测试似乎证实了这一点。其他人可以确认吗?
  • 我看到 DispatchQueue.AutoreleaseFrequency 是具有 .inherit、.never 和 .workItem 的新类型。这些是什么意思?我对 GCD 和自动释放进行了一些研究,但我对自动释放池的概念不是很熟悉。

【问题讨论】:

    标签: swift grand-central-dispatch swift3 xcode8


    【解决方案1】:

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

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

    DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM 以这种自动释放频率调度队列,在异步提交给它的每个块的执行期间推送和弹出一个自动释放池。

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

    【讨论】:

      【解决方案2】:

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

      在新的 DispatchQueue.Attributes 中,.serial 不再是成员。 这是否意味着没有 .concurrent 会创建一个串行队列。 我在 Swift Playgrounds 中进行的初步测试似乎证实了这一点。能 还有人确认吗?

      是的。队列可以是串行的,也可以是并发的。您创建的大多数队列都是串行的,因此如果您不希望使用默认行为,则只需将它们设置为并发即可。

      我看到 DispatchQueue.AutoreleaseFrequency 是一个新类型 .inherit、.never 和 .workItem。这些是什么意思?我做了一些 关于 GCD 和自动发布的研究,但我不是很熟悉 自动释放池的概念。

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

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

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

      .workItem:为每个被执行的项目创建和排出一个自动释放池

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

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


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

      【讨论】:

      • Apple 有一个习惯是经常对新事物进行不良记录,而且他们是否会回来进行记录可能会受到打击或错过。 UIInputView 上的 allowsSelfSizing 属性自 iOS 9 以来就已经存在,没有添加任何文档来解释它有什么效果,而且无论它设置为能够更改大小的任何方式似乎都没有任何效果。
      猜你喜欢
      • 2018-09-18
      • 2021-12-07
      • 1970-01-01
      • 2019-06-11
      • 1970-01-01
      • 2019-03-07
      • 1970-01-01
      • 2018-05-09
      • 2020-03-07
      相关资源
      最近更新 更多