2016-07-14 6 views
5

最近このWWDC GCDの話が見られました。何か問題があると思います。 DispatchQueuesを使用してプロパティをスレッドセーフにすることについてです。彼らは、プロパティをロックするDispatchQueueを使用GCDを使用してSwift 3のプロパティを同期

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 } 
     } 
    } 
} 

。しかし、のinternalQueueが同時に発生する可能性があるため、このスニペットは有効ではないと思います。したがって、内部キューがシリアルでない場合、2つの異なるDispatchQueues/Threadsからセッターを呼び出すと、スレッドの問題につながる可能性があります。私の理解では、同期は起動しているスレッドを保持していて、タスクが完了すれば続行するからです。このスニペットについてどう思いますか?私が間違っている?

+4

はい、internalQueueを* serial *ディスパッチキューとして定義します。 –

答えて

6

しかし、私はinternalQueueが

同時なる可能性があるため、このスニペットは、有効ではないと思う。しかし、それは同時ではありません。作成するディスパッチキューは、デフォルトではシリアルです。それがテクニックのポイントです(とその例)。

+0

GCDのWWDCビデオは、これまでの年代から見ることができます。この点は明らかです。 – matt

+0

ありがとうマット、私はそれを知らなかった。 –

7

ディスパッチバリアを使用して書き込み中にすべて同時にブロックすることができるようにする別の方法を示したいと思います。そのアプローチで

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 } 
    } 
    } 
} 

、キュー上で同時に発生する可能性があります読みますが、書き込みが原因の障壁に、排他的に実行されています。

これは、書籍Effective Objective C 2.0(Matt Galloway著)で説明されている方法のSwift 3変換です。

+1

ニース。また、プライベートな同時キューを使用することもできます。 –

+0

[この質問](http://stackoverflow.com/q/38084482/819340)は、 '.barrier'オプションに関するより多くの文脈を提供しています。 –

+0

@Rob私は今すぐ修正するつもりです。 – Andrea

関連する問題