420 votes

Comment créer une file d'attente en Swift 3 ?

Dans Swift 2, j'ai pu créer une file d'attente avec le code suivant :

let concurrentQueue = dispatch_queue_create("com.swift3.imageQueue", DISPATCH_QUEUE_CONCURRENT)

Mais cela ne compile pas dans Swift 3.

Quelle est la meilleure façon d'écrire cela en Swift 3 ?

2 votes

0 votes

Swift 4 a 3 paramètres supplémentaires pour créer une file d'attente en série. Comment les utiliser pour créer une file d'attente en série ? DispatchQueue.init(label : , qos : , attributes : , autoreleaseFrequency : , target : )

0 votes

@nr5 Les files d'attente sont sérielles par défaut, il est donc suffisant d'utiliser simplement DispatchQueue(label: "your-label") pour une file d'attente en série. Les paramètres supplémentaires ont tous des valeurs par défaut.

1174voto

LC 웃 Points 15362

Création d'une file d'attente concurrente

let concurrentQueue = DispatchQueue(label: "queuename", attributes: .concurrent)
concurrentQueue.sync {

}  

Créer une file d'attente en série

let serialQueue = DispatchQueue(label: "queuename")
serialQueue.sync { 

}

Obtenir la file d'attente principale de manière asynchrone

DispatchQueue.main.async {

}

Obtenir la file d'attente principale de manière synchrone

DispatchQueue.main.sync {

}

Pour obtenir un des fils de fond

DispatchQueue.global(qos: .background).async {

}

Xcode 8.2 beta 2 :

Pour obtenir un des fils de fond

DispatchQueue.global(qos: .default).async {

}

DispatchQueue.global().async {
    // qos' default value is ´DispatchQoS.QoSClass.default`
}

Si vous voulez apprendre à utiliser ces files d'attente, consultez ce document. réponse

4 votes

Vous pouvez en fait omettre attributes: .serial lors de la création d'une file d'attente en série : let serialQueue = DispatchQueue(label: "queuename") .

15 votes

Dans Xcode 8 beta 4 il n'y a pas d'option .serial donc vous devez créer une file d'attente en série en omettant le .concurrent dans les attributs.

0 votes

J'ai besoin d'accéder à la DispatchQueue depuis Swift3 dans objc mais j'ai obtenu l'erreur suivante Cannot initialize a variable of type '__strong dispatch_queue_t' (aka 'NSObject<OS_dispatch_queue> *__strong') with an rvalue of type 'OS_dispatch_queue * _Nonnull' when doing dispatch_queue_t backgroundQueue = [SwiftClass Queue] ; that is a static variable of DispatchQueueue in swift

57voto

t1ser Points 1167

Compile sous Swift 3 . Cet exemple contient la plupart de la syntaxe dont nous avons besoin.

QoS - nouvelle syntaxe de la qualité de service

weak self - pour perturber les cycles de rétention

si le self n'est pas disponible, ne rien faire

async global background queue - pour l'interrogation du réseau

async main queue - pour avoir touché l'interface utilisateur.

Bien sûr, vous devez ajouter un contrôle d'erreur à cela...

DispatchQueue.global(qos: .background).async { [weak self] () -> Void in

    guard let strongSelf = self else { return }

    strongSelf.flickrPhoto.loadLargeImage { loadedFlickrPhoto, error in

        if error != nil {
            print("error:\(error)")
        } else {
            DispatchQueue.main.async { () -> Void in
                activityIndicator.removeFromSuperview()
                strongSelf.imageView.image = strongSelf.flickrPhoto.largeImage
            }
        }
    }
}

7 votes

Lorsque vous codez en Swift 3, habituez-vous à condenser et à supprimer 30 % de votre code précédent :-)

0 votes

Merci pour l'exemple de [soi faible] !

1 votes

C'est mieux de guard que self n'est pas nil en haut, de sorte qu'aucune partie du code ne soit exécutée si elle est nil par exemple, guard strongSelf = self else { return } .

29voto

R Thomas Points 9

Compilé en XCode 8, Swift 3 https://github.com/rpthomas/Jedisware

 @IBAction func tap(_ sender: AnyObject) {

    let thisEmail = "emailaddress.com"
    let thisPassword = "myPassword" 

    DispatchQueue.global(qos: .background).async {

        // Validate user input

        let result = self.validate(thisEmail, password: thisPassword)

        // Go back to the main thread to update the UI
        DispatchQueue.main.async {
            if !result
            {
                self.displayFailureAlert()
            }

        }
    }

}

16voto

Cosmin Points 104

Puisque la question de l'OP a déjà été répondue ci-dessus, je veux juste ajouter quelques considérations de vitesse :

Le choix de la classe de priorité que vous attribuez à votre fonction asynchrone dans la section DispatchQueue.global .

Je ne recommande pas d'exécuter des tâches avec l'option .background La priorité des threads, en particulier sur l'iPhone X, où la tâche semble être allouée aux cœurs de faible puissance.

Voici quelques données réelles provenant d'une fonction à forte intensité de calcul qui lit un fichier XML (avec mise en mémoire tampon) et effectue une interpolation de données :

Nom du dispositif / .background / .utilitaire / .par défaut / .userInitiated / .userInteractive

  1. iPhone X : 18,7 s / 6,3 s / 1,8 s / 1,8 s / 1,8 s
  2. iPhone 7 : 4,6s / 3,1s / 3,0s / 2,8s / 2,6s
  3. iPhone 5s : 7,3s / 6,1s / 4,0s / 4,0s / 3,8s

Notez que l'ensemble des données n'est pas le même pour tous les appareils. Il est le plus grand sur l'iPhone X et le plus petit sur l'iPhone 5s.

1 votes

Grande information. Cela m'a aidé

1 votes

@Myk Si l'utilisateur a initié et/ou s'il attend les résultats, vous devriez utiliser .userInitiated o .userInteractive donc toute autre opération est retournée en arrière. Dans la plupart des autres cas .par défaut serait un bon choix.

6voto

Asfand Shabbir Points 628

C'est ce que j'ai fait et c'est particulièrement important si vous voulez rafraîchir votre interface utilisateur pour afficher de nouvelles données sans que l'utilisateur s'en aperçoive comme dans UITableView ou UIPickerView.

    DispatchQueue.main.async
 {
   /*Write your thread code here*/
 }

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