Цель наличия синхронизирующего потока - PullRequest
0 голосов
/ 12 ноября 2018

Следующий фрагмент кода предположительно устанавливает потокобезопасный синглтон:

class Singleton {
    static var shared = Singleton()
    private let internalQueue = DispatchQueue(label: "SingletionInternalQueue", qos: .default, attributes: .concurrent)

    private var _foo: String = "aaa"

    var foo: String {
        get {
            return internalQueue.sync { _foo }
        }
        set (newState) {
            internalQueue.async(flags: .barrier) { self._foo = newState }
        }
    }

    func setup(string: String) {
        foo = string
    }
}

Источник: Потокобезопасный синглтон в Swift

Но я не понимаю цели этого.

Например, если я хочу get значение foo, разве я не смогу просто прочитать его? Операция всегда должна выполняться в основном потоке, так какой смысл добавлять другой поток?

Аналогично с set: если меня беспокоит то, что несколько источников одновременно устанавливают значение, не можем ли мы упростить этот код и исключить параметр .barrier?

internalQueue.async(flags: .barrier) { self._foo = newState}

Если он находится в блоке sync, разве это не вызывает его в основном потоке? Если это так, то почему код должен быть только self._foo = newState?

1 Ответ

0 голосов
/ 12 ноября 2018

Вы правы: пока вы получаете доступ только к синглтону из основного потока, синхронизация не требуется. В этом случае я бы предпочел сделать это явным требованием, используя такой код:

assert(Thread.isMainThread)

Это будет оптимизировано в производственных сборках, но обеспечит обнаружение непреднамеренных ошибок программирования в режиме отладки (например, при вызове кода из обработчика завершения URLSession).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...