web-dev-qa-db-fra.com

Comment écrire dispatch_after GCD dans Swift 3 et 4?

Dans Swift 2, j’ai pu utiliser dispatch_after pour retarder une action à l’aide de la grande répartition centrale:

var dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC))) 
dispatch_after(dispatchTime, dispatch_get_main_queue(), { 
    // your function here 
})

Mais cela ne semble plus être compilé dans Swift 3 (ou 4). Quelle est la méthode préférée pour écrire cela dans Swift 3 (en utilisant la nouvelle API Dispatch)?

392
brandonscript

La syntaxe est simplement:

// to run something in 0.1 seconds

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
    // your code here
}

Notez que la syntaxe ci-dessus pour ajouter seconds en tant que Double semble être une source de confusion (surtout depuis que nous étions habitués à ajouter nsec). Cette syntaxe "ajouter des secondes en tant que Double" fonctionne car deadline est un DispatchTime et, dans les coulisses, il existe un opérateur + qui prend un Double et ajoute autant de secondes à DispatchTime:

public func +(time: DispatchTime, seconds: Double) -> DispatchTime

Toutefois, si vous voulez vraiment ajouter un nombre entier de msec, μs ou nsec à DispatchTime, vous pouvez également ajouter un DispatchTimeInterval à un DispatchTime. Cela signifie que vous pouvez faire:

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) {
    os_log("500 msec seconds later")
}

DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(1_000_000)) {
    os_log("1m μs seconds later")
}

DispatchQueue.main.asyncAfter(deadline: .now() + .nanoseconds(1_500_000_000)) {
    os_log("1.5b nsec seconds later")
}

Tout cela fonctionne de manière transparente en raison de cette méthode de surcharge distincte pour l'opérateur + dans la classe DispatchTime.

public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime
982
Rob

Swift 4:

DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
   // Code
}

Pour le temps .seconds(Int), .microseconds(Int) et .nanoseconds(Int) peuvent également être utilisés.

119
Hannes Sverrisson

Si vous voulez juste la fonction de délai dans

Swift 4

func delay(delay: Double, closure: @escaping () -> ()) {

     DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
          closure()
     }
}

Vous pouvez l'utiliser comme:

delay(delay: 1) { 
    print("Hi!")
}
52
rockdaswift

après la sortie de Swift 3, le @escaping doit aussi être ajouté

func delay(_ delay: Double, closure: @escaping () -> ()) {
  DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
    closure()
  }
}
16
Marco Pappalardo

Swift 4

Vous pouvez créer une extension sur DispatchQueue et ajouter un délai de fonction utilisant la fonction DispatchQueue asyncAfter en interne.

extension DispatchQueue {
   static func delay(_ delay: DispatchTimeInterval, closure: @escaping () -> ()) {
      DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: closure)
   }
}

et utilise 

DispatchQueue.delay(.milliseconds(10)) {
   print("task to be done")
}
5
Suhit Patil

Une saveur quelque peu différente de la réponse acceptée.

Swift 4

DispatchQueue.main.asyncAfter(deadline: .now() + 0.1 + .milliseconds(500) + 
.microseconds(500) + .nanoseconds(1000)) {
                print("Delayed by 0.1 second + 500 milliseconds + 500 microseconds + 
                      1000 nanoseconds)")
 }
4

appeler DispatchQueue.main.after(when: DispatchTime, execute: () -> Void)

Je recommande fortement d'utiliser les outils Xcode pour convertir en Swift 3 (Édition> Convertir> En syntaxe Swift actuelle). Il a attrapé ceci pour moi 

3
jjatie

Swift 5 et plus

DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute: {
   // code to execute                 
})
1
midhun p

Dans Swift 4.1 et Xcode 9.4.1

La réponse simple est ...

//To call function after 5 seconds time
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
//Here call your function
}
0
iOS

Vous pouvez utiliser

DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(100)) {
        // Code
    }
0
Parth Dhorda

essaye ça

let when = DispatchTime.now() + 1.5
    DispatchQueue.main.asyncAfter(deadline: when) {
        //some code
    }
0
A.Guz

Cela a fonctionné pour moi dans Swift 3

let time1 = 8.23
let time2 = 3.42

// Delay 2 seconds


DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
    print("Sum of times: \(time1 + time2)")
}
0
Ankit garg

Aucune des réponses mentionnées ne fonctionnait sur un thread non principal, ajoutant donc mes 2 centimes. 

Sur file d'attente principale (thread principal) 

let mainQueue = DispatchQueue.main
let deadline = DispatchTime.now() + .seconds(10)
mainQueue.asyncAfter(deadline: deadline) {
    // ...
}

OR

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .seconds(10)) { 
    // ...
}

On global queue (pas de thread principal, basé sur la qualité de service spécifiée). 

let backgroundQueue = DispatchQueue.global()
let deadline = DispatchTime.now() + .milliseconds(100)
backgroundQueue.asyncAfter(deadline: deadline, qos: .background) { 
    // ...
}

OR

DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + .milliseconds(100), qos: .background) {
    // ...
}
0
MANN