2016-06-14 6 views
317

Swift 2, j'ai pu utiliser dispatch_after pour retarder une action en utilisant grande expédition centrale:Comment écrire dispatch_after GCD dans Swift 3 et 4?

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 compiler Swift 3 (ou 4). Quel est le moyen préféré d'écrire ceci dans Swift 3 (en utilisant la nouvelle API Dispatch)?

+5

Pour plus d'informations sur le processus de migration peuvent être trouvés ici: [https://swift.org/migration-guide/](https : //swift.org/migration-guide/) La section "Dispatch" est-elle pertinente pour cette question – tonik12

+0

si votre question est "UInt64"? – Honey

Répondre

770

La syntaxe est simplement:

// to run something in 0.1 seconds 

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

Notez la syntaxe ci-dessus d'ajouter seconds comme Double semble être une source de confusion (en particulier parce que nous étions habitués à ajouter nsec). « AJOUT secondes comme Double » fonctionne syntaxe parce deadline est un DispatchTime et, dans les coulisses, il y a un opérateur + qui prendra un Double et d'ajouter que de nombreuses secondes à la DispatchTime:

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

Mais, si vous voulez vraiment ajouter un nombre entier de msec, μs ou nsec au 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") 
} 

Tous ces fonctionnent 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 
+4

Merci de le signaler, et en fait https://swift.org/migration-guide/ mentionne la nécessité de faire ce changement à la main. – matt

+1

Oh, désolé. C'est trop tard ici :). Pensé que tout le désordre devrait aller réellement, mais n'a pas fait le saut. IMO la solution "simple" est la solution unique. – duemunk

+1

@Rob comment pourrais-je l'annuler? Merci. – rottenoats

4

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

Je recommande fortement d'utiliser les outils Xcode pour convertir à Swift 3 (Edition> Convertir> Pour Swift Current Syntax). Il a pris pour moi

85

Swift 4:

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

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

+0

@brandonscript C'est code propre –

+5

'.milliseconds' est mieux que Double. –

+3

Très bien. Une note pour les autres: vous pouvez également utiliser l'une des autres valeurs d'énumération 'DispatchTimeInterval'. 'case secondes (Int)' 'case millisecondes (Int)' 'case microsecondes (Int)' 'case nanosecondes (Int)' –

38

Si vous voulez juste la fonction de retard 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!") 
} 
+0

DispatchQueue.main.asyncAfter (date limite:) ne fonctionne pas. Il dit qu'il ne surcharge aucune méthode de sa superclasse. –

+0

Utilisez-vous la même version xcode que celle spécifiée? – rockdaswift

+2

'DispatchQueue.main.asyncAfter (date limite: .now() + 0.1, execute: closure)' est plus simple. –

14

après la libération rapide de 3, également @escaping a à ajouter

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

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)") 
} 
+4

Vous ne savez pas en quoi cela diffère de la réponse acceptée? – brandonscript

0

Vous pouvez créer une fonction performAfter qui utilise la fonction Swift 3 de DispatchAfter interne

func performAfter(delay: TimeInterval, completion: @escaping() -> Void) { 
    DispatchQueue.main.asyncAfter(deadline: .now() + delay) { 
     completion() 
    } 
} 

et utiliser

performAfter(delay: 2) { 
    print("task to be done") 
} 
+1

En quoi est-ce différent de la réponse de @ rockdaswift? – brandonscript

+0

comme je l'ai mentionné wraps asyncAfter dans la fonction performAfter qui prend le retard en paramètre et il peut être plus facile d'appeler en utilisant simplement performAfter (delay: 2) {} – suhit

+1

Tout comme ... – brandonscript

0

Vous pouvez utiliser

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

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

essayer

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

Vous ne savez pas en quoi cela est différent de la réponse affectée? – brandonscript