A sintaxe é simplesmente:
// to run something in 0.1 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
// your code here
}
Observe que a sintaxe acima de adicionar seconds
como a Double
parece ser uma fonte de confusão (especialmente porque estávamos acostumados a adicionar o nsec). A Double
sintaxe "adicionar segundos como " funciona porque deadline
é um DispatchTime
e, nos bastidores, há um +
operador que fará um Double
e adicionará muitos segundos ao DispatchTime
:
public func +(time: DispatchTime, seconds: Double) -> DispatchTime
Mas, se você realmente deseja adicionar um número inteiro de ms, ms ou nsec ao DispatchTime
, também pode adicionar um DispatchTimeInterval
a a DispatchTime
. Isso significa que você pode fazer:
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")
}
Tudo isso funciona perfeitamente por causa desse método de sobrecarga separado para o +
operador da DispatchTime
classe.
public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime
Foi perguntado como alguém cancela uma tarefa despachada. Para fazer isso, use DispatchWorkItem
. Por exemplo, isso inicia uma tarefa que será acionada em cinco segundos ou, se o controlador de exibição for descartado e desalocado, deinit
cancelará a tarefa:
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() { ... }
}
Observe o uso da [weak self]
lista de captura no DispatchWorkItem
. Isso é essencial para evitar um forte ciclo de referência. Observe também que isso não faz um cancelamento preventivo, mas apenas interrompe o início da tarefa, se ainda não o tiver feito. Mas se já tiver iniciado no momento em que encontrar a cancel()
chamada, o bloco concluirá sua execução (a menos que você esteja verificando manualmente isCancelled
dentro do bloco).