Синтаксис просто:
// to run something in 0.1 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
// your code here
}
Зауважимо, вищевказаний синтаксис додавання secondsяк Doubleздається є джерелом плутанини (особливо, оскільки ми звикли додавати nsec). Цей Doubleсинтаксис "додати секунди як " працює тому, що deadlineє, DispatchTimeа за лаштунками є +оператор, який займе a Doubleі додасть стільки секунд до DispatchTime:
public func +(time: DispatchTime, seconds: Double) -> DispatchTime
Але якщо ви дійсно хочете додати до числа ціле число msec, μs або nsec DispatchTime, ви також можете додати DispatchTimeIntervala 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всередині блоку).