Как сделать многопоточность, параллелизм или параллелизм в 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)
}
Другие вопросы по тегам