Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/97.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios getter和setter自定义并发队列同步上的竞速条件_Ios_Swift_Grand Central Dispatch_Swift4 - Fatal编程技术网

Ios getter和setter自定义并发队列同步上的竞速条件

Ios getter和setter自定义并发队列同步上的竞速条件,ios,swift,grand-central-dispatch,swift4,Ios,Swift,Grand Central Dispatch,Swift4,我有以下代码,据我所知,这些代码应该提供对\u的线程安全读写。我的isolationQueue是一个并发队列,因此需要保持不变。我在此队列上调用多个独立的异步操作来计算各种图像的预测。不同调用之间的唯一共享项是设置预测时的值 var isolationQueue = DispatchQueue.global(qos: .default) var _predictions: [Int:[Prediction]] = [:] var predictions:[Int: [Predict

我有以下代码,据我所知,这些代码应该提供对
\u
的线程安全读写。我的isolationQueue是一个并发队列,因此需要保持不变。我在此队列上调用多个独立的异步操作来计算各种图像的预测。不同调用之间的唯一共享项是设置预测时的值

  var isolationQueue = DispatchQueue.global(qos: .default)
  var _predictions: [Int:[Prediction]] = [:]

  var predictions:[Int: [Prediction]] {
    get {
      var result: [Int: [Prediction]]!
      isolationQueue.sync {
        result = _predictions
      }
      return result
    }
    set(value) {
      isolationQueue.sync {
        self._predictions = value
      }
    }
  }
然而,由于某些原因,线程消毒剂似乎检测到getter和setter之间的竞速情况


我遗漏了什么吗?

全局调度队列是并发队列,因此它们不能是并发队列 用于防止并发访问资源

为此,您应该定义自己的串行调度队列:

var isolationQueue = DispatchQueue(label: "my.queue.identifier") 

对于您的情况,使用DispatchSemaphore()更简单,开销更小。代码看起来像

var isolationSem = DispatchSemaphore(value: 1)
var _predictions: [Int:[Prediction]] = [:]

var predictions:[Int: [Prediction]] {
  get {
    var result: [Int: [Prediction]]!
    isolationSem.wait()
    result = _predictions
    isolationSem.signal()
    return result
  }
  set(value) {
    isolationSem.wait()
    self._predictions = value
    isolationSem.signal()
  }
}

有关DispatchSemaphore不适用的情况,请参阅。

isolationQueue是如何定义的?是串行调度队列吗?更新了问题。它是全球性的,因此我相信它会同时发生
var isolationQueue=DispatchQueue.global(qos:.默认值)
在并发队列中执行时,使用
sync
不会防止其他线程访问资源?在并发队列上是否还有确保串行访问的方法?@RezaShirazian:
sync
意味着调用线程等待完成,但从不同线程调度的块可以同时执行。下面是对4种可能组合的一个很好的概述:。我该如何处理
sync
呢?如果我的
isolationQueue
是串行的
sync
在这种情况下似乎没有多大意义。@RezaShirazian:
isolationQueue.async{…}
将立即返回,而不等待执行该项。同步/异步和串行/并发是独立的参数。请看一看并尝试一下(您可以在setter上使用
async
,但不能在getter方法上使用。)谢谢Martin。我想我明白了。首先,我的队列需要保持并发,因为我需要运行多个独立的异步操作来计算预测。将我的setter设置为
async(标志:.barrier)
可确保在设置预测字典时,此队列上的其他操作不会修改它。