Di Swift 2, saya bisa menggunakan dispatch_after
untuk menunda tindakan menggunakan grand central dispatch:
var dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC)))
dispatch_after(dispatchTime, dispatch_get_main_queue(), {
// your function here
})
Tetapi ini sepertinya tidak lagi dikompilasi sejak Swift 3. Apa cara yang disukai untuk menulis ini dalam Swift modern?
swift
swift4
grand-central-dispatch
swift5
naskah merek
sumber
sumber
UInt64
?Jawaban:
Sintaksnya sederhana:
Catatan, sintaksis menambahkan di
seconds
atasDouble
tampaknya menjadi sumber kebingungan (terutama karena kita terbiasa menambahkan nsec).Double
Sintaks "tambahkan detik sebagai " berfungsi karenadeadline
merupakanDispatchTime
dan, di belakang layar, ada+
operator yang akan mengambilDouble
dan menambahkan banyak detik keDispatchTime
:Tetapi, jika Anda benar-benar ingin menambahkan bilangan bulat dari msec, μs, atau nsec ke
DispatchTime
, Anda juga dapat menambahkan aDispatchTimeInterval
ke aDispatchTime
. Itu berarti Anda dapat melakukan:Ini semua berjalan mulus karena metode kelebihan beban yang terpisah ini untuk
+
operator diDispatchTime
kelas.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, tugasnyadeinit
akan dibatalkan:Perhatikan penggunaan
[weak self]
daftar tangkap diDispatchWorkItem
. 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 dengancancel()
panggilan, blok akan menyelesaikan eksekusi (kecuali jika Anda secara manual memeriksaisCancelled
di dalam blok).sumber
DispatchTimeInterval
penafsiran, seperti.milliseconds
membutuhkanInt
. Tetapi jika hanya menambahkan detik, saya akan menggunakanDouble
, misalnyalet n: Double = 1.0; queue.asyncAfter(deadline: .now() + n) { ... }
.Swift 4:
Untuk saat ini
.seconds(Int)
,.microseconds(Int)
dan.nanoseconds(Int)
dapat juga digunakan.sumber
.milliseconds
lebih baik daripada Double.DispatchTimeInterval
nilai enum lainnya .case seconds(Int)
case milliseconds(Int)
case microseconds(Int)
case nanoseconds(Int)
.milliseconds is better than Double.
- Saya ingin itu memakai T-shirt;).Jika Anda hanya ingin fungsi penundaan di
Swift 4 & 5
Anda bisa menggunakannya seperti:
sumber
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1, execute: closure)
lebih sederhana.setelah rilis Swift 3, @escaping juga harus ditambahkan
sumber
Rasa yang agak berbeda dari Jawaban yang Diterima.
Cepat 4
sumber
Cepat 4
Anda dapat membuat ekstensi di DispatchQueue dan menambahkan penundaan fungsi yang menggunakan
DispatchQueue
fungsi asyncAfter secara internaldan gunakan
sumber
panggilan
DispatchQueue.main.after(when: DispatchTime, execute: () -> Void)
Saya sangat merekomendasikan menggunakan alat Xcode untuk mengkonversi ke Swift 3 (Edit> Convert> To Current Swift Syntax). Ini menangkap ini untukku
sumber
Dalam Swift 4.1 dan Xcode 9.4.1
Jawaban sederhana adalah ...
sumber
Cepat 5 dan lebih tinggi
sumber
Tidak ada jawaban yang disebutkan berjalan di utas non-utama, jadi tambahkan 2 sen saya.
Di antrian utama (utas utama)
ATAU
Pada antrian global (utas bukan utama, berdasarkan QOS yang ditentukan).
ATAU
sumber
Ini bekerja untuk saya di Swift 3
sumber
Kamu bisa menggunakan
sumber
coba ini
sumber