252 votes

Comment puis-je dispatch_sync, dispatch_async, dispatch_after, etc dans Swift 3, Swift 4, et au-delà?

J'ai beaucoup de code Swift 2.x (ou même 1.x) les projets qui ressemble à ceci:

// Move to a background thread to do some long running work
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
    let image = self.loadOrGenerateAnImage()
    // Bounce back to the main thread to update the UI
    dispatch_async(dispatch_get_main_queue()) {
        self.imageView.image = image
    }
}

Ou des trucs de ce genre de retarder l'exécution:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(0.5 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) {
    print("test")
}

Ou de l'une de toutes sortes de d'autres utilisations de la Grand Central Dispatch API...

Maintenant que j'ai ouvert mon projet dans Xcode 8 (bêta) pour Swift 3, je reçois toutes sortes d'erreurs. Certains d'entre eux offrent à corriger mon code, mais pas tous les correctifs de produire du code du travail. Que dois-je faire à ce sujet?

351voto

rickster Points 19870

Depuis le début, Swift a fourni des équipements pour la fabrication de ObjC et C plus Swifty, en ajoutant plus avec chaque version. Maintenant, dans Swift 3, la nouvelle "l'importation en tant que membre de la" fonctionnalité permet aux cadres de certains styles d'API C -- où vous avez un type de données qui fonctionne comme une sorte de classe, et un tas de fonctions globales de travailler avec elle -- agir plus comme Swift-Api natives. Les types de données de l'importation, de Swift, de classes, de leurs fonctions globales d'importation que les méthodes et les propriétés de ces classes, et des choses comme des ensembles de constantes peuvent devenir des sous-types, le cas échéant.

Dans Xcode 8 / Swift 3 bêta, Apple a appliqué cette fonction (avec quelques autres) pour faire de l'Envoi cadre beaucoup plus Swifty. (Et Graphiques de Base, aussi.) Si vous avez été à la suite de la Swift open-source efforts, ce n'est pas un scoop, mais c'est la première fois qu'il fait partie de Xcode.

Votre première étape sur le déplacement de tout projet Swift 3 devrait être pour l'ouvrir dans Xcode 8 et choisissez Modifier > Convertir > Pour Swift Actuel, Syntaxe... dans le menu. Cela s'applique (avec votre examen et d'approbation) tous les changements à la fois nécessaire pour que toutes les renommée des Api et d'autres changements. (Souvent, une ligne de code est affecté par plus d'un de ces changements à la fois, afin de répondre à l'erreur fixer ses individuellement peut pas tout gérer, à droite.)

Le résultat est que le modèle commun pour rebondir de travail à l'arrière-plan et l'arrière ressemble maintenant à ceci:

// Move to a background thread to do some long running work
DispatchQueue.global(qos: .userInitiated).async {
    let image = self.loadOrGenerateAnImage()
    // Bounce back to the main thread to update the UI
    DispatchQueue.main.async {
        self.imageView.image = image
    }
}

Notez que nous utilisons .userInitiated , au lieu de l'une des plus vieilles DISPATCH_QUEUE_PRIORITY des constantes. La qualité de Service (QoS) des prescripteurs ont été mis en place dans OS X 10.10 / iOS 8.0, fournissant une manière plus claire pour le système pour donner la priorité au travail et de la dépréciation de l'ancien priorité les prescripteurs. Voir Apple docs sur le travail de fond et de l'efficacité énergétique pour plus de détails.

Par ailleurs, si vous êtes en gardant votre propre files d'attente pour organiser le travail, de la façon d'obtenir un ressemble maintenant à ceci (notez qu' DispatchQueueAttributes est OptionSet, si vous utilisez de la collection de style littéraux à combiner les options):

class Foo { 
    let queue = DispatchQueue(label: "com.example.my-serial-queue",
                           attributes: [.serial, .qosUtility])
    func doStuff() {
        queue.async {
            print("Hello World")
        }
    }
}

À l'aide de dispatch_after à travailler plus tard? C'est une méthode sur les files d'attente, trop, et il prend un DispatchTime, ce qui a des opérateurs pour divers types numériques, de sorte que vous pouvez simplement ajouter des entiers ou des fractions de secondes:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { // in half a second...
    print("Are we there yet?")
}

Vous pouvez trouver votre chemin autour de la nouvelle Expédition de l'API par l'ouverture de son interface dans Xcode 8 -- utilisation d'Ouvrir Rapidement à trouver le module d'Expédition, ou de mettre un symbole (comme DispatchQueue) dans votre projet Swift/aire de jeux et de commande cliquez sur, puis brouse autour du module à partir de là. (Vous pouvez trouver l'Swift Envoi de l'API d'Apple dans la spiffy nouvelle Référence de l'API de site web et Xcode doc viewer, mais il semble que la doc du contenu à partir de la version de C n'a pas déménagé dans l'instant.)

Voir le Guide de Migration pour plus de conseils.

147voto

ingconti Points 405

Dans Xcode beta 8 4 ne fonctionne pas...

Utilisation:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
    print("Are we there yet?")
}

pour async deux façons:

DispatchQueue.main.async {
    print("Async1")
}

DispatchQueue.main.async( execute: {
    print("Async2")
})

73voto

S. Matsepura Points 1303

Celui-ci est un bon exemple pour Swift 4 sur async:

DispatchQueue.global(qos: .background).async {
    // Background Thread
    DispatchQueue.main.async {
        // Run UI Updates or call completion block
    }
}

40voto

Marco Points 359

dans Xcode 8 utilisation:

DispatchQueue.global(qos: .userInitiated).async { }

31voto

Saranjith Points 4137

Swift 4

Principal et l'arrière-plan des Files d'attente

let main = DispatchQueue.main
let background = DispatchQueue.global()
let helper = DispatchQueue(label: "another_thread") 

Travailler avec async et de synchroniser les threads!

 background.async { //async tasks here } 
 background.sync { //sync tasks here } 

Async des threads de travail avec le thread principal.

La synchronisation des threads de bloquer le thread principal lors de l'exécution.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X