2016-07-14 83 views
5

Ho guardato questi anni WWDC GCD parlare ultimamente e penso che ci sia uno snippet di codice con cui qualcosa non va. Si tratta di rendere una proprietà thread safe utilizzando DispatchQueues.Sincronizza proprietà in Swift 3 tramite GCD

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

usano un DispatchQueue per bloccare una proprietà. Ma penso che questo snippet non sia valido, perché il valore internalQueue potrebbe essere simultaneo. Quindi, se chiamiamo il setter da due diversi DispatchQueues/Thread se quella coda interna non è seriale, potrebbe anche portare a problemi di threading giusto? Perché nella mia comprensione sincronizzazione tiene solo il thread di richiamo e continua se l'attività è completa. Cosa ne pensi di questo frammento? Ho sbagliato?

+4

Sì, si definirà internalQueue come una coda di invio * seriale *. –

risposta

6

ma penso che questo frammento di codice non è valido, perché l'internalQueue potrebbe essere concomitante

Ma non è concomitante. Le code di invio create sono di serie per impostazione predefinita. Questo è il punto della tecnica (e l'esempio).

+0

Si potrebbe desiderare di guardare video WWDC su GCD degli anni precedenti. Sono più chiari su questo punto. – matt

+0

Grazie Matt, non lo sapevo. –

7

Mi piacerebbe solo mostrare un altro approccio che ti permette di leggere contemporaneamente, ma bloccare tutto mentre scrivi usando una barriera di spedizione.

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

Con questo approccio, si legge possono verificarsi contemporaneamente sulla coda, ma le scritture sono eseguite esclusivamente, a causa della barriera.

Questa è solo una conversione Swift 3 di un approccio spiegato nel libro Effective Objective C 2.0, scritto da Matt Galloway.

+1

Bello. Potrebbe anche usare una coda concorrente privata qui. –

+0

[Questa domanda] (http://stackoverflow.com/q/38084482/819340) fornisce più contesto sull'opzione '.barrier'. –

+0

@Rob grazie che ho intenzione di risolvere ora. – Andrea