Синтаксис просто:
// 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
, ви також можете додати 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
всередині блоку).