Saya memiliki metode yang menerima blok dan blok penyelesaian. Blok pertama harus berjalan di latar belakang, sedangkan blok penyelesaian harus berjalan dalam antrian apa pun yang dipanggil metode tersebut.
Untuk yang terakhir saya selalu menggunakan dispatch_get_current_queue()
, tetapi sepertinya itu sudah usang di iOS 6 atau lebih tinggi. Apa yang harus saya gunakan?
dispatch_get_current_queue()
tidak digunakan lagi di iOS 6? para dokter tidak mengatakan apa-apa tentang ituJawaban:
Pola "jalankan di antrean apa pun yang digunakan penelepon" memang menarik, tetapi pada akhirnya bukan ide yang bagus. Antrean tersebut dapat berupa antrean prioritas rendah, antrean utama, atau antrean lain dengan properti ganjil.
Pendekatan favorit saya untuk ini adalah dengan mengatakan "blok penyelesaian berjalan pada implementasi yang ditentukan antrian dengan properti ini: x, y, z", dan biarkan pengiriman blok ke antrian tertentu jika pemanggil menginginkan kontrol lebih dari itu. Serangkaian properti khas untuk ditentukan akan menjadi sesuatu seperti "serial, non-reentrant, dan async sehubungan dengan antrian aplikasi-terlihat lainnya".
** EDIT **
Catfish_Man memberi contoh pada komentar di bawah, saya hanya menambahkannya ke jawabannya.
sumber
Ini pada dasarnya adalah pendekatan yang salah untuk API yang Anda jelaskan. Jika API menerima blok dan blok penyelesaian untuk dijalankan, fakta-fakta berikut harus benar:
"Block to run" harus dijalankan pada antrian internal, misalnya antrian yang privat ke API dan karenanya sepenuhnya di bawah kendali API itu. Satu-satunya pengecualian untuk ini adalah jika API secara khusus menyatakan bahwa blok akan dijalankan di antrean utama atau salah satu antrean serentak global.
Blok penyelesaian harus selalu dinyatakan sebagai tupel (antrian, blok) kecuali asumsi yang sama seperti untuk # 1 berlaku benar, misalnya blok penyelesaian akan dijalankan pada antrian global yang diketahui. Blok penyelesaian selanjutnya harus dikirim secara asinkron pada antrian yang diteruskan.
Ini bukan hanya poin gaya, mereka sepenuhnya diperlukan jika API Anda ingin aman dari kebuntuan atau perilaku edge-case lainnya yang AKAN menggantung Anda dari pohon terdekat suatu hari nanti. :-)
sumber
Jawaban lainnya bagus, tapi bagi saya jawabannya struktural. Saya memiliki metode seperti ini di Singleton:
yang memiliki dua dependensi, yaitu:
dan
Dengan cara itu saya memusatkan panggilan saya untuk dikirim ke utas lainnya.
sumber
Anda harus berhati-hati saat menggunakannya
dispatch_get_current_queue
. Dari file header:Anda dapat melakukan salah satu dari dua hal berikut:
Simpan referensi ke antrean tempat Anda awalnya diposting (jika Anda membuatnya melalui
dispatch_queue_create
), dan gunakan sejak saat itu.Gunakan antrian yang ditentukan sistem lewat
dispatch_get_global_queue
, dan pantau antrean mana yang Anda gunakan.Secara efektif sementara sebelumnya mengandalkan sistem untuk melacak antrian Anda, Anda harus melakukannya sendiri.
sumber
dispatch_get_current_queue()
untuk mengetahui antrian mana itu? Terkadang kode yang perlu mengetahui antrian mana yang dijalankan tidak memiliki kontrol atau pengetahuan apa pun tentangnya. Saya memiliki banyak kode yang dapat (dan harus) dijalankan pada antrian latar belakang tetapi kadang-kadang perlu memperbarui gui (bilah kemajuan, dll), dan oleh karena itu perlu dispatch_sync () ke antrian utama untuk operasi tersebut. Jika sudah ada di antrian utama, dispatch_sync () akan terkunci selamanya. Saya butuh waktu berbulan-bulan untuk mengubah kode saya untuk ini.Apple sudah tidak digunakan lagi
dispatch_get_current_queue()
, tetapi meninggalkan lubang di tempat lain, jadi kami masih bisa mendapatkan antrean pengiriman saat ini:Ini berfungsi untuk antrian utama setidaknya. Perhatikan,
underlyingQueue
properti itu tersedia sejak iOS 8.Jika Anda perlu melakukan blok penyelesaian dalam antrian asli, Anda juga dapat menggunakan
OperationQueue
secara langsung, maksud saya tanpa GCD.sumber
Bagi mereka yang masih perlu membandingkan antrian, Anda bisa membandingkan antrian dengan label mereka atau menentukan. Periksa https://stackoverflow.com/a/23220741/1531141 ini
sumber
Ini adalah jawaban saya juga. Jadi saya akan berbicara tentang kasus penggunaan kami.
Kami memiliki lapisan layanan dan lapisan UI (di antara lapisan lainnya). Lapisan layanan menjalankan tugas di latar belakang. (Tugas manipulasi data, tugas CoreData, panggilan Jaringan, dll.). Lapisan layanan memiliki beberapa antrian operasi untuk memenuhi kebutuhan lapisan UI.
Lapisan UI bergantung pada lapisan layanan untuk melakukan tugasnya dan kemudian menjalankan blok penyelesaian sukses. Blok ini dapat memiliki kode UIKit di dalamnya. Contoh penggunaan sederhana adalah untuk mendapatkan semua pesan dari server dan memuat ulang tampilan koleksi.
Di sini kami menjamin bahwa blok yang diteruskan ke lapisan layanan dikirim pada antrean tempat layanan dipanggil. Karena dispatch_get_current_queue adalah metode yang tidak digunakan lagi, kami menggunakan NSOperationQueue.currentQueue untuk mendapatkan antrean pemanggil saat ini. Catatan penting tentang properti ini.
Karena kami selalu menjalankan layanan kami pada antrean yang diketahui (antrean khusus kami dan antrean Utama), ini berfungsi dengan baik untuk kami. Kami memiliki kasus di mana serviceA dapat memanggil serviceB yang dapat memanggil serviceC. Karena kami mengontrol dari mana panggilan layanan pertama dilakukan, kami tahu layanan lainnya akan mengikuti aturan yang sama.
Jadi NSOperationQueue.currentQueue akan selalu mengembalikan salah satu Antrean kami atau MainQueue.
sumber