Skip to main content

Dispatch Queue

Разница между DispathchQueue..sync{} и DispathchQueue..async{}#

DispathchQueue..sync{} - block and wait
DispathchQueue..async{} - dispatch and proceed

Когда нельзя использовать sync вызов? Когда запуск кода происходит с того же потока, на котором запускается. Например:

DispatchQueue.main.sync {     print("sync call from main thread on main thread")}

Результат: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).

Так как sync вызов блокирует поток и ждет выполнения кложура, сам кложур на этом же потоке выполниться не может, так как он заблокирован ожиданием выполнения самого себя. Получается deadlock.

Это касается не только главной очереди, можно с тем же результатом положить и другую:

let myQueue = DispatchQueue(label: "MyOwnQueue") myQueue.sync {    myQueue.sync {        print("sync call on my own queue")    }}

global() так положить не получится, так как она имеет несколько потоков:

DispatchQueue.global(qos: .userInteractive).sync {    DispatchQueue.global(qos: .userInteractive).sync {        print("call main.sync from background thread")    }}

Когда использовать sync? Когда нужно дождаться выполнения кода в другом треде прежде чем продолжить выполнение:

DispatchQueue.global().async {    var x = 0         DispatchQueue.main.sync {        x += 1    }         print(x)}

если сделать инкремент в async вызове, то в консоль выведется 0, а sync - 1