GCD - asyncAfter: как запустить его синхронно - PullRequest
0 голосов
/ 26 января 2020

Я только начал читать swift, и в настоящее время я не понимаю, как правильно использовать многопоточность.

То, что я пытаюсь достичь в следующем блоке кода, - это выполнить операторы печати внутри диспетчеры, но я хочу сделать это по порядку. Проблема, которая у меня есть, состоит в том, что, конечно, я хочу сделать это в фоновом потоке, а не в главном, поскольку это длинная задача, и в то же время выполнить ее по порядку, пока я даю задержку в выполнении. Текущий блок выполняет все случаи вместе.

Я также взглянул на Таймер и Семафоры, но безрезультатно.

Любая помощь или объяснение того, что я делаю неправильно или что я должен подойти будет оценено.

let formattedSeries = ["a", "a", "b"]
let dispatchQueue = DispatchQueue(label: "taskQueue")
let a = 1000
let b = 5000
for (index, letter) in (formattedSeries.enumerated()){

    switch letter {
    case "a":
        dispatchQueue.asyncAfter(deadline: .now() + .milliseconds(a), execute: {
            print("a executed")           
        })      
        break
    case "b":
        dispatchQueue.asyncAfter(deadline: .now() + .milliseconds(b), execute: {
            print("b executed")
        })
        break
    default:
        print("default")
    }
}

Ответы [ 2 ]

2 голосов
/ 26 января 2020

Для выполнения задач по порядку необходима асинхронная операция.

  1. Используйте класс AsynchronousOperation, указанный в этот ответ
  2. Создать серийный номер OperationQueue и установите maxConcurrentOperationCount на 1
  3. Подкласс AsynchronousOperation и поместите задачи dispatchQueue.asyncAfter в метод main() подкласса. Вызовите finish() в закрытии (до или после print("a executed"))
  4. Добавьте операции в очередь последовательных операций
1 голос
/ 26 января 2020

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

let dispatchGroup = DispatchGroup()
let dispatchQueue = DispatchQueue(label: "taskQueue")
let a = 1000
let b = 5000
let formattedSeries = "abbaabba"
print("start", Date().timeIntervalSince1970)
for (index, letter) in (formattedSeries.enumerated()){
    dispatchGroup.enter()
    switch letter {
    case "a":
        dispatchQueue.asyncAfter(deadline: .now() + .milliseconds(a), execute: {
            print("a executed", Date().timeIntervalSince1970)
            dispatchGroup.leave()
        })
        break
    case "b":
        dispatchQueue.asyncAfter(deadline: .now() + .milliseconds(b), execute: {
            print("b executed", Date().timeIntervalSince1970)
            dispatchGroup.leave()
        })
        break
    default:
        print("default")
    }
    dispatchGroup.wait()
}

Я добавил дополнительный вывод для подтверждения правильности интервалов. Выходные данные

start 1580060250.3307471
a executed 1580060251.389974
b executed 1580060256.889923
b executed 1580060262.2758632
a executed 1580060263.372933
a executed 1580060264.373787
b executed 1580060269.37443
b executed 1580060274.375314
a executed 1580060275.4726748

, что доказывает, что мы оценили буквы по порядку, и что интервалы async_after между отпечатками проходят.

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