2016-07-14 2 views
5

Я смотрел в этом году WWDC GCD говорить в последнее время, и я думаю, что есть фрагмент кода, с которым что-то не так. Речь идет о том, чтобы сделать свойство потокобезопасным, используя DispatchQueues.Синхронизация свойств в Swift 3 с использованием 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 } 
     } 
    } 
} 

Они используют DispatchQueue заблокировать свойство. Но я думаю, что этот снипп недействителен, потому что internalQueue может быть одновременно. Итак, если мы вызываем сеттер из двух разных DispatchQueues/Threads, если эта внутренняя очередь не является последовательной, это также может привести к проблемам с потоками? Потому что в моем понимании синхронизация просто удерживает вызывающий поток и продолжается, если задача завершена. Что вы думаете об этом фрагменте? Я ошибаюсь?

+4

Да, вы бы определили innerQueue как * serial * dispatch queue. –

ответ

6

Но я думаю, что этот фрагмент не является действительным, поскольку internalQueue может быть одновременно

Но не одновременно. Выбранные очереди отправки по умолчанию являются серийными. Это точка техники (и пример).

+0

Возможно, вы захотите посмотреть видеоролики WWDC на GCD с ранних лет. Они более ясны в этом вопросе. – 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 } 
    } 
    } 
} 

При таком подходе, читает может происходить одновременно на очереди, но запись выполняется исключительно из-за барьер.

Это всего лишь конверсия Swift 3, описанная в книге Эффективная цель C 2.0, написанная Matt Galloway.

+1

Ницца. Здесь также можно использовать приватную параллельную очередь. –

+0

[Этот вопрос] (http://stackoverflow.com/q/38084482/819340) предоставляет больше контекста в опции '.barrier'. –

+0

@Rob спасибо, я сейчас исправлю. – Andrea

Смежные вопросы