【问题标题】:Synchronize Properties in Swift 3 using GCD使用 GCD 在 Swift 3 中同步属性
【发布时间】:2016-07-14 11:45:26
【问题描述】:

我最近看了今年的 WWDC GCD 演讲,我认为代码 sn-p 有问题。它是关于使用 DispatchQueues 使属性成为线程安全的。

class MyObject {
    private var internalState: Int
    private let internalQueue: DispatchQueue // Serial or Concurrent?

    var state: Int {
        get {
            return internalQueue.sync { internalState }
        }

        set (newState) {
            internalQueue.sync { internalState = newState }
        }
    }
}

他们使用 DispatchQueue 来锁定属性。但我认为这个 sn-p 无效,因为 internalQueue 可能是并发的。因此,如果我们从两个不同的 DispatchQueues/Threads 调用 setter,如果该内部队列不是串行的,也可能导致线程问题,对吧?因为在我的理解中,同步只是保持调用线程并在任务完成时继续。你觉得这个sn-p怎么样?我错了吗?

【问题讨论】:

  • 是的,您可以将 internalQueue 定义为 serial 调度队列。

标签: swift grand-central-dispatch swift3


【解决方案1】:

我只想展示另一种方法,它可以让您同时读取,但在写入时使用调度屏障阻塞所有内容。

class MyObject {
private var internalState: Int
private let internalQueue = DispatchQueue(label: "reader-writer", attributes: .concurrent)

var state: Int {
    get {
        return internalQueue.sync { internalState }
    }

    set (newState) {
        internalQueue.async(flags: .barrier) { internalState = newState }
    }
  }
}

使用这种方法,可以在队列上同时进行读取,但由于障碍,写入会以独占方式执行。

这只是由 Matt Galloway 编写的Effective Objective C 2.0一书中解释的一种方法的 Swift 3 转换。

【讨论】:

  • 不错。也可以在这里使用私有并发队列。
  • This question 提供了有关 .barrier 选项的更多上下文。
【解决方案2】:

但我认为这个 sn-p 无效,因为 internalQueue 可能是并发的

但它不是并发的。默认情况下,您创建的调度队列是串行的。这就是技术(和示例)的重点。

【讨论】:

  • 您可能想在 GCD 上观看早些年的 WWDC 视频。他们在这一点上更清楚。
  • 谢谢马特,我不知道。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多