Saya telah menggunakan DispatchQueue.main.async
waktu yang lama untuk melakukan operasi terkait UI.
Swift menyediakan DispatchQueue.main.async
dan DispatchQueue.main.sync
, dan keduanya dilakukan di antrean utama.
Adakah yang bisa memberi tahu saya perbedaan di antara mereka? Kapan saya harus menggunakan masing-masing?
DispatchQueue.main.async {
self.imageView.image = imageView
self.lbltitle.text = ""
}
DispatchQueue.main.sync {
self.imageView.image = imageView
self.lbltitle.text = ""
}
sumber
DispatchQueue.main.sync
dari utas latar belakang?async
sana? Maksud saya karena tidak ada yang lain di utas setelah itu maka tidak ada bedanya. Jika demikianDispatchQueue.main.sync {block1}; DispatchQueue.main.sync {block2};
maka itu akan masuk akal. Tetapi ketika tidak ada blok lain maka saya tidak dapat memikirkan manfaat menggunakanDispatchQueue.main.sync {Oneblock}
lebihDispatchQueue.main.async {Oneblock}
. Untuk keduanya, mereka akan mendapatkan prioritas / kesegeraan mainQueue dan tidak ada yang akan mengganggu mereka.Mengapa Concurrency?
Segera setelah Anda menambahkan tugas-tugas berat ke aplikasi Anda seperti pemuatan data, itu memperlambat kerja UI Anda atau bahkan membekukannya. Concurrency memungkinkan Anda melakukan 2 tugas atau lebih "secara bersamaan". Kerugian dari pendekatan ini adalah keamanan benang yang tidak selalu mudah dikendalikan. Fe ketika tugas yang berbeda ingin mengakses sumber daya yang sama seperti mencoba mengubah variabel yang sama pada utas yang berbeda atau mengakses sumber daya yang sudah diblokir oleh utas yang berbeda.
Ada beberapa abstraksi yang perlu kita waspadai.
Antrian
Harus serial atau bersamaan . Serta global atau pribadi pada saat bersamaan.
Dengan antrian serial, tugas akan diselesaikan satu per satu sementara dengan antrian bersamaan, tugas akan dilakukan secara bersamaan dan akan diselesaikan pada jadwal yang tidak terduga. Kelompok tugas yang sama akan menghabiskan lebih banyak waktu pada antrian serial dibandingkan dengan antrian bersamaan.
Anda dapat membuat antrean pribadi Anda sendiri (baik serial atau bersamaan ) atau menggunakan antrean global (sistem) yang sudah tersedia . The antrian utama adalah satu-satunya antrian seri dari semua antrian global yang .
Sangat disarankan untuk tidak melakukan tugas berat yang tidak dirujuk ke pekerjaan UI pada antrean utama (fe memuat data dari jaringan), tetapi melakukannya di antrean lain untuk menjaga UI tidak membeku dan responsif terhadap tindakan pengguna. Jika kami membiarkan UI diubah pada antrian lain, perubahan dapat dilakukan pada jadwal dan kecepatan yang berbeda dan tidak terduga. Beberapa elemen UI dapat digambar sebelum atau setelah dibutuhkan. Itu bisa merusak UI. Kita juga perlu mengingat bahwa karena antrian global adalah antrian sistem, ada beberapa tugas lain yang dapat dijalankan oleh sistem di dalamnya.
Kualitas Layanan / Prioritas
Antrian juga memiliki qos berbeda (Kualitas Layanan) yang menetapkan prioritas pelaksanaan tugas (dari yang tertinggi ke terendah di sini):
.userInteractive - antrian utama
.userInitiated - untuk tugas yang dimulai pengguna di mana pengguna menunggu beberapa respons
.utility - untuk tugas yang membutuhkan waktu dan tidak memerlukan respons segera, misalnya bekerja dengan data
.background - untuk tugas-tugas yang tidak terkait dengan bagian visual dan yang tidak ketat untuk waktu penyelesaian).
Ada juga antrian
default yang tidak mentransfer informasi qos . Jika tidak mungkin mendeteksi qos theqos akan digunakan antara .userInitiated dan .utility .
Tugas dapat dilakukan secara sinkron atau asinkron .
Fungsi sinkron mengembalikan kontrol ke antrian saat ini hanya setelah tugas selesai. Ini memblokir antrian dan menunggu sampai tugas selesai.
Fungsi asynchronous mengembalikan kontrol ke antrian saat ini tepat setelah tugas dikirim untuk dilakukan pada antrian yang berbeda. Itu tidak menunggu sampai tugas selesai. Itu tidak memblokir antrian.
Masalah Umum.
Kesalahan paling populer yang dibuat programmer saat memproyeksikan aplikasi bersamaan adalah sebagai berikut:
JANGAN PERNAH memanggil fungsi sinkronisasi pada antrian utama .
Jika Anda memanggil fungsi sinkronisasi pada antrian utama, itu akan memblokir antrian serta antrian akan menunggu tugas diselesaikan tetapi tugas tidak akan pernah selesai karena itu bahkan tidak akan bisa dimulai karena antriannya sudah diblokir. Ini disebut deadlock .
Kapan menggunakan sinkronisasi? Kapan kita perlu menunggu sampai tugas selesai. Fe ketika kita memastikan bahwa beberapa fungsi / metode tidak dipanggil ganda. Fe kita memiliki sinkronisasi dan berusaha mencegahnya menjadi panggilan ganda sampai benar-benar selesai. Berikut beberapa kode untuk masalah ini:
Bagaimana cara mengetahui penyebab error crash report pada perangkat IOS?
sumber
DispatchQueue.main.sync
dari utas latar belakang?GCD
memungkinkan Anda untuk menjalankan tugassynchronously
atauasynchronously
[Tentang]synchronous
Fungsi (blok dan tunggu) mengembalikan kontrol saat tugas akan diselesaikanasynchronous
(dispatch dan lanjutkan) fungsi mengembalikan kontrol segera, mengirimkan tugas untuk memulai antrian yang sesuai tetapi tidak menunggu sampai selesai.[DispatchQueue]
sumber
sync
atauasync
metode tidak berpengaruh pada antrian di mana mereka dipanggil.sync
akan memblokir benang dari yang disebut dan tidak antrian di mana ia disebut. Ini adalah propertiDispatchQueue
yang memutuskan apakahDispatchQueue
akan menunggu eksekusi tugas (antrian serial) atau dapat menjalankan tugas berikutnya sebelum tugas saat ini selesai (antrian bersamaan).Jadi, meskipun
DispatchQueue.main.async
panggilan asinkron, operasi tugas berat yang ditambahkan di dalamnya dapat membekukan UI karena operasinya dijalankan secara serial pada thread utama. Jika metode ini dipanggil dari thread latar belakang, kontrol akan kembali ke thread tersebut secara instan bahkan saat UI tampak terhenti. Ini karenaasync
panggilan dilakukanDispatchQueue.main
sumber