Saya ingin menjeda aplikasi saya pada titik tertentu. Dengan kata lain, saya ingin aplikasi saya mengeksekusi kode, tetapi kemudian pada titik tertentu, berhenti selama 4 detik, dan kemudian melanjutkan dengan sisa kode. Bagaimana saya bisa melakukan ini?
Saya menggunakan Swift.
Jawaban:
Alih-alih tidur, yang akan mengunci program Anda jika dipanggil dari utas UI, pertimbangkan untuk menggunakan
NSTimer
atau pengatur waktu pengiriman.Tapi, jika Anda benar-benar membutuhkan penundaan di utas saat ini:
Ini menggunakan
sleep
fungsi dari UNIX.sumber
Menggunakan
dispatch_after
blok dalam banyak kasus lebih baik daripada menggunakansleep(time)
sebagai benang yang tidur dilakukan diblokir dari melakukan pekerjaan lain. saat menggunakandispatch_after
utas yang sedang dikerjakan tidak diblokir sehingga dapat melakukan pekerjaan lain sementara itu.Jika Anda bekerja pada utas utama aplikasi Anda, menggunakan
sleep(time)
buruk untuk pengalaman pengguna aplikasi Anda karena UI tidak responsif selama waktu itu.Pengiriman setelah menjadwalkan eksekusi blok kode alih-alih membekukan utas:
Cepat ≥ 3.0
Cepat <3.0
sumber
.now() + .seconds(4)
memberi kesalahan:expression type is ambiguous without more context
.now() + .seconds(5)
hanya.now() + 5
Perbandingan antara berbagai pendekatan di swift 3.0
1. Tidur
Metode ini tidak memiliki panggilan balik. Letakkan kode langsung setelah baris ini untuk dieksekusi dalam 4 detik. Ini akan menghentikan pengguna dari pengulangan dengan elemen UI seperti tombol tes sampai waktu hilang. Meskipun tombolnya agak beku saat tidur, elemen lain seperti indikator aktivitas masih berputar tanpa beku. Anda tidak dapat memicu tindakan ini lagi selama tidur.
2. Pengiriman, Lakukan dan Timer
Tiga metode ini bekerja dengan cara yang sama, mereka semua berjalan di latar belakang dengan panggilan balik, hanya dengan sintaks yang berbeda dan fitur yang sedikit berbeda.
Pengiriman biasanya digunakan untuk menjalankan sesuatu di utas latar belakang. Ini memiliki panggilan balik sebagai bagian dari panggilan fungsi
Perform sebenarnya adalah timer yang disederhanakan. Ini mengatur timer dengan penundaan, dan kemudian memicu fungsi dengan pemilih.
Dan akhirnya, timer juga menyediakan kemampuan untuk mengulangi panggilan balik, yang tidak berguna dalam kasus ini
Untuk ketiga metode ini, ketika Anda mengklik tombol untuk memicu mereka, UI tidak akan membeku dan Anda diizinkan untuk mengkliknya lagi. Jika Anda mengklik tombol lagi, timer lain sudah diatur dan panggilan balik akan dipicu dua kali.
Kesimpulannya
Tidak satu pun dari empat metode ini yang bekerja dengan cukup baik sendiri.
sleep
akan menonaktifkan interaksi pengguna, sehingga layar " membeku " (tidak benar-benar) dan menghasilkan pengalaman pengguna yang buruk. Tiga metode lainnya tidak akan membekukan layar, tetapi Anda dapat memicu mereka beberapa kali, dan sebagian besar waktu, Anda ingin menunggu sampai Anda mendapatkan panggilan kembali sebelum mengizinkan pengguna untuk melakukan panggilan lagi.Jadi desain yang lebih baik akan menggunakan salah satu dari tiga metode async dengan pemblokiran layar. Ketika pengguna mengklik tombol, tutup seluruh layar dengan beberapa tampilan transparan dengan indikator aktivitas berputar di atas, memberi tahu pengguna bahwa klik tombol sedang ditangani. Kemudian hapus tampilan dan indikator dalam fungsi panggilan balik, memberi tahu pengguna bahwa tindakan tersebut ditangani dengan benar, dll.
sumber
@objc
di depan fungsi panggilan balik untukperform(...)
opsi. Seperti itu:@objc func callback() {
Saya setuju dengan Palle bahwa menggunakan
dispatch_after
adalah pilihan yang baik di sini. Tapi Anda mungkin tidak suka panggilan GCD karena cukup mengganggu untuk ditulis . Alih-alih, Anda dapat menambahkan pembantu praktis ini :Sekarang Anda cukup menunda kode Anda pada utas latar belakang seperti ini:
Menunda kode di utas utama bahkan lebih sederhana:
Jika Anda lebih suka Kerangka yang juga memiliki beberapa fitur yang lebih berguna maka checkout HandySwift . Anda dapat menambahkannya ke proyek Anda melalui Carthage atau Accio lalu menggunakannya persis seperti pada contoh di atas:
sumber
DispatchTime
tidak tersedia di Swift 2.let dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(seconds * Double(NSEC_PER_SEC)))
Sebelumnya.Anda juga dapat melakukan ini dengan Swift 3.
Lakukan fungsi setelah penundaan seperti itu.
sumber
Di Swift 4.2 dan Xcode 10.1
Anda memiliki total 4 cara untuk menunda. Keluar dari opsi ini 1 lebih disukai untuk memanggil atau menjalankan fungsi setelah beberapa waktu. The tidur () adalah paling tidak kasus digunakan.
Pilihan 1.
Pilihan 2.
Opsi 3.
Opsi 4.
Jika Anda ingin memanggil fungsi setelah beberapa waktu untuk mengeksekusi sesuatu jangan gunakan sleep .
sumber
NSTimer
Jawaban oleh @nneonneo menyarankan untuk menggunakan
NSTimer
tetapi tidak menunjukkan bagaimana melakukannya. Ini adalah sintaks dasar:Ini adalah proyek yang sangat sederhana untuk menunjukkan bagaimana itu dapat digunakan. Ketika sebuah tombol ditekan, ia memulai timer yang akan memanggil fungsi setelah penundaan setengah detik.
Menggunakan
dispatch_time
(seperti pada jawaban Palle ) adalah pilihan lain yang valid. Namun, sulit untuk membatalkan . DenganNSTimer
, untuk membatalkan acara yang tertunda sebelum itu terjadi, yang perlu Anda lakukan hanyalah meneleponPenggunaan
sleep
tidak disarankan, terutama pada utas utama, karena menghentikan semua pekerjaan yang dilakukan pada utas.Lihat di sini untuk jawaban saya yang lebih lengkap.
sumber
Coba implementasi berikut di Swift 3.0
Pemakaian
sumber
Anda dapat membuat ekstensi untuk menggunakan fungsi penundaan dengan mudah (Sintaks: Swift 4.2+)
Cara menggunakan di UIViewController
sumber
Jika Anda perlu mengatur penundaan kurang dari satu detik, Anda tidak perlu mengatur parameter .seconds. Saya harap ini bermanfaat bagi seseorang.
sumber
sumber
DispatchQueue.main.asyncAfter(deadline: .now() + 4) {/*Do stuff*/}
Mungkin lebih benar ✌️Jika kode Anda sudah berjalan di utas latar, jeda utas menggunakan metode ini di Yayasan :
Thread.sleep(forTimeInterval:)
Sebagai contoh:
(Lihat jawaban lain untuk saran saat kode Anda berjalan di utas utama.)
sumber
Untuk membuat penundaan waktu yang sederhana, Anda dapat mengimpor Darwin dan kemudian menggunakan sleep (detik) untuk melakukan penundaan. Namun, itu hanya membutuhkan waktu beberapa detik, jadi untuk pengukuran yang lebih tepat, Anda dapat mengimpor Darwin dan menggunakan sleep (sepersejuta detik) untuk pengukuran yang sangat tepat. Untuk menguji ini, saya menulis:
Yang mencetak, lalu menunggu selama 1 detik dan mencetak, kemudian menunggu selama 0,4 detik kemudian mencetak. Semua bekerja seperti yang diharapkan.
sumber
ini yang paling sederhana
sumber