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 seconds
come aggiunta Double
sembra essere una fonte di confusione (specialmente da quando eravamo abituati ad aggiungere nsec). La Double
sintassi "aggiungi secondi come " funziona perché deadline
è un DispatchTime
e, dietro le quinte, c'è un +
operatore che impiegherà un Double
e 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 DispatchTimeInterval
a 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 DispatchTime
classe.
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, deinit
annullerà 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 isCancelled
all'interno del blocco).