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 seconds
tant que a Double
semble être une source de confusion (d'autant plus que nous étions habitués à ajouter nsec). Cette Double
syntaxe «ajouter des secondes en tant que » fonctionne car il deadline
s'agit d'un DispatchTime
et, dans les coulisses, il existe un +
opérateur qui prendra un Double
et 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 DispatchTime
classe.
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é, deinit
il 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' isCancelled
intérieur du bloc).