Ответ 1
Скажем, у вас была какая-то функция:
func calculate(foo: String, bar: Int) -> Int {
// slow calculations performed here
return result
}
Если вы хотите сделать это асинхронно, вы можете обернуть его примерно так:
func calculate(foo: String, bar: Int, completionHandler: @escaping (Int) -> Void) {
DispatchQueue.global().async {
// slow calculations performed here
completionHandler(result)
}
}
Или, альтернативно, если вы хотите, чтобы обработчик завершения всегда вызывался в основной очереди, вы также можете сделать это для себя:
func calculate(foo: String, bar: Int, completionHandler: @escaping (Int) -> Void) {
DispatchQueue.global().async {
// slow calculations performed here
DispatchQueue.main.async {
completionHandler(result)
}
}
}
Для работы, выполняемой в фоновом режиме, вы можете использовать другую приоритетную фоновую очередь или использовать свою собственную пользовательскую очередь или собственную очередь операций. Но эти детали не являются существенными для вопроса.
Что имеет значение, так это то, что сама эта функция не возвращает никакого значения, даже несмотря на то, что основная синхронная функция выполняет. Вместо этого это асинхронное представление передает значение обратно через закрытие completionHandler
. Таким образом, вы будете использовать его так:
calculate(foo: "life", bar: 42) { result in
// we can use the `result` here (e.g. update model or UI accordingly)
print("the result is = \(result)")
}
// but don't try to use `result` here, because we get here immediately, before
// the above slow, asynchronous process is done
(FYI, все приведенные выше примеры - Swift 3. Для версии Swift 2.3 см. предыдущую версию этого ответа.)