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 de l'ajout en secondstant que a Doublesemble être une source de confusion (d'autant plus que nous étions habitués à ajouter nsec). Cette Doublesyntaxe «ajouter des secondes en tant que » fonctionne car il deadlines'agit d'un DispatchTimeet, dans les coulisses, il existe un +opérateur qui prendra un Doubleet ajoutera autant de secondes au DispatchTime:
public func +(time: DispatchTime, seconds: Double) -> DispatchTime
Mais, si vous voulez vraiment ajouter un nombre entier de ms, μ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")
}
Tout cela fonctionne parfaitement grâce à cette méthode de surcharge distincte pour l' +opérateur de la DispatchTimeclasse.
public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime
Il a été demandé comment procéder pour annuler une tâche envoyée. Pour ce faire, utilisez DispatchWorkItem. Par exemple, cela démarre une tâche qui se déclenchera dans cinq secondes, ou si le contrôleur de vue est rejeté et désalloué, deinitil annulera la tâche:
class ViewController: UIViewController {
private var item: DispatchWorkItem?
override func viewDidLoad() {
super.viewDidLoad()
item = DispatchWorkItem { [weak self] in
self?.doSomething()
self?.item = nil
}
DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: item!)
}
deinit {
item?.cancel()
}
func doSomething() { ... }
}
Notez l'utilisation de la [weak self]liste de capture dans le DispatchWorkItem. Ceci est essentiel pour éviter un cycle de référence fort. Notez également que cela n'effectue pas une annulation préventive, mais arrête simplement la tâche de démarrer si ce n'est pas déjà fait. Mais s'il a déjà commencé au moment où il rencontre l' cancel()appel, le bloc terminera son exécution (sauf si vous vérifiez manuellement l' isCancelledintérieur du bloc).