Могу ли я использовать DispatchSemaphore для управления потоком в главной очереди?
Видимо, я могу использовать DispatchSemaphore, только если имею дело с разными очередями. Но что, если я хочу запустить асинхронный код в той же очереди (в данном случае основной очереди).
let s = DispatchSemaphore(value : 0)
DispatchQueue.main.async {
s.signal()
}
s.wait()
Этот фрагмент не работает, потому что асинхронный код также ожидает, потому что семафор заблокировал основную очередь. Могу ли я сделать это с семафором? Или мне нужно запустить асинхронный код в другой очереди?
пс. Я знаю, что мог бы использовать синхронизацию вместо асинхронного и семафорного в этом фрагменте. Но это всего лишь пример кода для воспроизведения асинхронного вызова.
1 ответ
Все это в основной теме, поэтому semaphore.signal()
никогда не будет вызван, потому что поток остановится на semaphore.wait()
и не продолжать.
Если вы пытаетесь запустить какой-то асинхронный код и основной поток ожидает его, запустите этот код в другой очереди и попросите его проинформировать семафор, когда это будет сделано, что позволит основному потоку продолжить.
что, если я хочу запустить асинхронный код в той же очереди (в данном случае в основной очереди).
Затем используйте DispatchGroup
вместо. Это не тоDispatchSemaphore
это для.
Запустите этот код на игровой площадке.
import Foundation
let d = DispatchGroup()
var v:Int = 1
d.enter()
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
v = 7
d.leave()
}
d.notify(queue: DispatchQueue.main) {
print("v = \(v)")
}
На выходе будет v = 7
. Если вы закомментируетеd.enter()
а также d.leave()
тогда вывод будет v = 1
.
Если я вызываю async, разве я не запускаю этот код в другом потоке?
Нет, вам нужно понимать циклы выполнения потоков в целом и цикл основных событий iOS в частности.