Синтаксис просто:
// to run something in 0.1 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
// your code here
}
Обратите внимание, что приведенный выше синтаксис добавления seconds
как a Double
кажется источником путаницы (особенно если мы привыкли добавлять nsec). Этот Double
синтаксис «добавить секунды как » работает, потому что deadline
есть DispatchTime
и, за кадром, есть +
оператор, который возьмет Double
и добавит столько секунд к DispatchTime
:
public func +(time: DispatchTime, seconds: Double) -> DispatchTime
Но если вы действительно хотите добавить целое число msec, μs или nsec к DispatchTime
, вы также можете добавить a DispatchTimeInterval
к a DispatchTime
. Это означает, что вы можете сделать:
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")
}
Все это без проблем работает благодаря этому отдельному методу перегрузки для +
оператора в DispatchTime
классе.
public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime
Был задан вопрос, как отменить отправленное задание. Для этого используйте DispatchWorkItem
. Например, это запускает задачу, которая будет запущена через пять секунд, или, если контроллер представления уволен и освобожден, deinit
он отменит задачу:
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() { ... }
}
Обратите внимание на использование [weak self]
списка захвата в DispatchWorkItem
. Это важно, чтобы избежать сильного референтного цикла. Также обратите внимание, что это не делает упреждающего отмены, а просто останавливает запуск задачи, если это еще не сделано. Но если он уже начался к тому времени, когда он встречает cancel()
вызов, блок завершит свое выполнение (если вы не проверяете вручную isCancelled
внутри блока).