Могу ли я использовать 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 в частности.

Другие вопросы по тегам