Sintaksnya sederhana:
// to run something in 0.1 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
// your code here
}
Catatan, sintaksis menambahkan di secondsatas Doubletampaknya menjadi sumber kebingungan (terutama karena kita terbiasa menambahkan nsec). DoubleSintaks "tambahkan detik sebagai " berfungsi karena deadlinemerupakan DispatchTimedan, di belakang layar, ada +operator yang akan mengambil Doubledan menambahkan banyak detik ke DispatchTime:
public func +(time: DispatchTime, seconds: Double) -> DispatchTime
Tetapi, jika Anda benar-benar ingin menambahkan bilangan bulat dari msec, μs, atau nsec ke DispatchTime, Anda juga dapat menambahkan a DispatchTimeIntervalke a DispatchTime. Itu berarti Anda dapat melakukan:
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")
}
Ini semua berjalan mulus karena metode kelebihan beban yang terpisah ini untuk +operator di DispatchTimekelas.
public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime
Ditanya bagaimana seseorang membatalkan tugas yang dikirim. Untuk melakukan ini, gunakan DispatchWorkItem. Misalnya, ini memulai tugas yang akan diaktifkan dalam lima detik, atau jika pengontrol tampilan diberhentikan dan tidak dialokasikan, tugasnya deinitakan dibatalkan:
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() { ... }
}
Perhatikan penggunaan [weak self]daftar tangkap di DispatchWorkItem. Ini penting untuk menghindari siklus referensi yang kuat. Perhatikan juga bahwa ini tidak melakukan pembatalan preemptive, tetapi hanya menghentikan tugas dari memulai jika belum. Tetapi jika sudah dimulai saat bertemu dengan cancel()panggilan, blok akan menyelesaikan eksekusi (kecuali jika Anda secara manual memeriksa isCancelleddi dalam blok).