Comment faire la lecture multiple, la concurrence ou le parallélisme dans iOS Swift?

y a-t-il un moyen de créer un worker thread dans Swift? par exemple, s'il y a une fonctionnalité majeure qui nécessite beaucoup de calculs et provoque donc un retard du thread principal de quelques secondes, si je souhaite déplacer cette fonctionnalité vers un thread séparé ou un thread qui ne bloque pas le thread principal, y a-t-il un moyen de le faire avec Swift?

j'ai passé en revue les composants de base et avancés de la Documentation Apple pour Swift mais il n'y a rien concurrence ou parallélisme, est-ce que quelqu'un sait quelque chose sur la façon de le faire(si possible)?

36
demandé sur Gabriel Southern 2014-07-05 22:52:09

3 réponses

ou vous pouvez aussi utiliser les files d'attente d'opération. Dans 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
    }
}

soit ceci, soit GCD, qui Andy illustré, beau travail.

voir Apple Guide De Programmation De La Concurrence pour les mérites relatifs des files d'attente d'opération et des files d'expédition (alias Grand Central Dispatch, GCD). Bien que ce guide illustre encore les exemples à L'aide de L'objectif-C, L'API et les concepts sont essentiellement les mêmes dans Swift (utilisez simplement la syntaxe Swift). Le la documentation pour les GCD et les files d'attente d'opération dans Xcode décrit à la fois les API Objective-C et Swift.


en passant, vous remarquerez que dans l'exemple ci-dessus ainsi que dans la démonstration de GCD D'Andy, nous avons utilisé des "fermetures de fuite". Par exemple, si vous regardez la définition de addOperationWithBlock, qui est défini comme une fonction avec un paramètre qui est une "fermeture" (qui est analogue à un bloc en Objective-C):

func addOperation(_ block: @escaping () -> Swift.Void)

cela pourrait vous conduire à supposer que vous invoquez - le comme suit:

queue.addOperation({
    // do something in the background
})

mais lorsque le dernier paramètre d'une fonction est une fermeture, la syntaxe de fermeture de queue vous permet de prendre ce paramètre de fermeture final hors des parenthèses de la fonction, et de le déplacer après la fonction, donnant:

queue.addOperation() {
    // do something in the background
}

et comme il ne reste plus rien dans les parenthèses, vous pouvez même aller un peu plus loin, et supprimer ces parenthèses vides:

queue.addOperation {
    // do something in the background
}

espérons que cela illustre comment interpréter la NSOperationQueue/OperationQueue et / ou des déclarations de fonction GCD et utilisez-les dans votre code.

45
répondu Rob 2017-05-23 12:26:07

Vous pouvez utiliser Grand Central Dispatch (GCD) pour de telles tâches.

Ceci est un exemple de base:

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)
17
répondu Andy 2014-07-05 19:18:13

Cette bibliothèque permet de décrire la concurrence de façon très expressive:

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)
}
0
répondu Alex Lynch 2018-01-25 16:56:30