La sintassi è semplicemente:
// to run something in 0.1 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
// your code here
}
Nota, la sintassi di cui sopra secondscome aggiunta Doublesembra essere una fonte di confusione (specialmente da quando eravamo abituati ad aggiungere nsec). La Doublesintassi "aggiungi secondi come " funziona perché deadlineè un DispatchTimee, dietro le quinte, c'è un +operatore che impiegherà un Doublee aggiungerà molti secondi a DispatchTime:
public func +(time: DispatchTime, seconds: Double) -> DispatchTime
Ma, se vuoi davvero aggiungere un numero intero di msec, μs o nsec a DispatchTime, puoi anche aggiungere DispatchTimeIntervala a DispatchTime. Ciò significa che puoi fare:
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")
}
Tutti questi funzionano perfettamente grazie a questo metodo di sovraccarico separato per l' +operatore della DispatchTimeclasse.
public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime
È stato chiesto come si fa a cancellare un compito inviato. Per fare questo, usa DispatchWorkItem. Ad esempio, questo avvia un'attività che si attiverà in cinque secondi, o se il controller di visualizzazione viene ignorato e deallocato, deinitannullerà l'attività:
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() { ... }
}
Si noti l'uso [weak self]dell'elenco di acquisizione in DispatchWorkItem. Ciò è essenziale per evitare un forte ciclo di riferimento. Si noti inoltre che ciò non comporta una cancellazione preventiva, ma piuttosto interrompe l'avvio dell'attività se non lo è già. Ma se è già iniziato quando incontra la cancel()chiamata, il blocco finirà la sua esecuzione (a meno che tu non stia controllando manualmente isCancelledall'interno del blocco).