Как сделать многопоточность, параллелизм или параллелизм в iOS Swift?
Есть ли способ создать рабочий поток в Swift? Например, если есть основная функциональность, которая требует много вычислений и, следовательно, вызывает задержку основного потока на несколько секунд, если я хочу переместить эту функциональность в отдельный поток или поток, который не блокирует основной поток, есть ли способ сделать это с помощью Swift?
Я ознакомился с основными и продвинутыми компонентами Apple Documentation for Swift, но нет ничего о параллелизме или параллелизме, кто-нибудь знает что-нибудь о том, как это сделать (если это возможно)?
3 ответа
Или вы также можете использовать очереди операций. В Swift 3:
let queue = OperationQueue()
queue.addOperation() {
// do something in the background
OperationQueue.main.addOperation() {
// when done, update your UI and/or model on the main queue
}
}
Либо это, либо GCD, который иллюстрировал Энди, работают нормально.
См. Руководство Apple по программированию параллелизма для получения информации об относительных достоинствах очередей операций и очередей отправки (также известной как Grand Central Dispatch, GCD). Хотя это руководство по-прежнему иллюстрирует примеры с использованием Objective-C, API и концепции в Swift практически одинаковы (просто используйте синтаксис Swift). Документация для GCD и очередей операций в Xcode описывает API Objective-C и Swift.
Кстати, вы заметите, что как в приведенном выше примере, так и в демонстрации GCD Энди мы использовали "замыкающие замыкания". Например, если вы посмотрите на определение addOperationWithBlock
, которая определяется как функция с одним параметром, который является "замыканием" (которое аналогично блоку в Objective-C):
func addOperation(_ block: @escaping () -> Swift.Void)
Это может привести вас к предположению, что вы будете вызывать его следующим образом:
queue.addOperation({
// do something in the background
})
Но когда последним параметром функции является замыкание, синтаксис конечного замыкания позволяет вам взять этот последний параметр замыкания из скобок функции и переместить его после функции, получив:
queue.addOperation() {
// do something in the background
}
А поскольку в скобках ничего не осталось, вы даже можете пойти еще дальше и удалить эти пустые скобки:
queue.addOperation {
// do something in the background
}
Надеюсь, это показывает, как интерпретировать NSOperationQueue
/ OperationQueue
и / или объявления функций GCD и использование их в вашем коде.
Вы можете использовать Grand Central Dispatch (GCD) для таких задач.
Это основной пример:
let backgroundQueue: dispatch_queue_t = dispatch_queue_create("com.a.identifier", DISPATCH_QUEUE_CONCURRENT)
// can be called as often as needed
dispatch_async(backgroundQueue) {
// do calculations
}
// release queue when you are done with all the work
dispatch_release(backgroundQueue)
Эта библиотека позволяет вам описать параллелизм в супер выразительной форме:
func handleError(_ error) { ... }
HoneyBee.start(on: DispatchQueue.main) { root in
root.setErrorHandler(handleError)
.chain(function1) // runs on main queue
.setBlockPerformer(DispatchQueue.global())
.chain(function2) // runs on background queue
.branch { stem in
stem.chain(func3) // runs in parallel with func4
+
stem.chain(func4) // runs in parallel with func3
}
.chain(func5) // runs after func3 and func4 have finished
.setBlockPerformer(DispatchQueue.main)
.chain(updateUIFunc)
}