Подтвердить что ты не робот

Как сделать многопоточность, concurrency или parallelism в iOS Swift?

Есть ли способ создать рабочий поток в Swift?, например, если есть большая функциональность, которая требует большого количества вычислений и, следовательно, заставляет основной поток задерживаться на несколько секунд, если я хотел бы переместить этот функциональность для отдельного потока или потока, который не блокирует основной поток, есть ли способ сделать это с помощью Swift?

Я прошел через базовые и расширенные компоненты Apple Documentation для Swift, но ничего о concurrency или parallelism ничего не знает о том, как это сделать (если возможно)?

4b9b3361

Ответ 1

Или вы также можете использовать очереди операций. В 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 и использовать их в вашем коде.

Ответ 2

Для таких задач вы можете использовать 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)

Ответ 3

Эта библиотека позволяет вам описать параллелизм в супер выразительной форме:

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)
}

Ответ 4

Вот лучший ресурс, чтобы узнать подробно о Councurrency