Sintaksnya sederhana:
// to run something in 0.1 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
// your code here
}
Catatan, sintaksis menambahkan di seconds
atas Double
tampaknya menjadi sumber kebingungan (terutama karena kita terbiasa menambahkan nsec). Double
Sintaks "tambahkan detik sebagai " berfungsi karena deadline
merupakan DispatchTime
dan, di belakang layar, ada +
operator yang akan mengambil Double
dan 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 DispatchTimeInterval
ke 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 DispatchTime
kelas.
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 deinit
akan 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 isCancelled
di dalam blok).