Grand Central Dispatch yoki GCD iOS ilovalarimizdagi ko‘p vazifalarni bajarish usulidir. Ushbu tizimning ishlash usuli shundan iboratki, bir qator vazifalarni yuborish navbatlariga yuborish mumkin, ular o'z navbatida bir nechta oqimlarda ishlaydi va oxir-oqibat tizim tomonidan boshqariladi.

Ko'pincha biz ilovalarimizdan birida UI-ni yangilamoqchi bo'lganimizda GCD haqida o'ylaymiz. Ushbu yangilanishlar asosiy ish zarrachasida sodir bo'ladi, ammo biz bajarishimiz kerak bo'lgan boshqa vazifalar ham bor va ular bir vaqtning o'zida yoki fonda ishlashi mumkin.

Ba'zi kontekstni qo'shish uchun navbat asosiy yoki fon oqimida sinxron yoki asinxron ravishda ishga tushirilishi mumkin bo'lgan kod blokidir.

Navbatdan foydalanganda biz Apple tomonidan taqdim etilgan global navbatdan foydalanishimiz yoki o'zimizning shaxsiy navbatlarimizni yaratishimiz mumkin. Shuni ta'kidlash kerakki, global navbatlardan ehtiyotkorlik bilan foydalanish kerak, chunki biz ularni suiiste'mol qilishni xohlamaymiz.

Ushbu tushunchalarning ba'zilari nimani anglatishini yaxshiroq tushunish uchun kodga o'tamiz va navbat yaratamiz.

let queue = DispatchQueue(label: “queue.1”)

Bu erda biz maxsus navbat yaratdik va unga noyob yorliq tayinladik. Siz bu yorliq deb atagan narsa mutlaqo o'zboshimchalik, lekin uni ilovangizga tegishli bo'lgan narsa deb nomlaganingiz ma'qul.

Biz ushbu navbatlarda async va sync kabi turli usullarni chaqirishimiz mumkin. Ushbu kalit so'zlar ilovamizga kodimizni qanday bajarish kerakligini aytib beradi.

Mana bizning kodimiz asosiy ish zarrachasida ishlaydigan kodga nisbatan fon zarrachasida sinxron ishlayotganiga misol.

// Background thread
queue.sync {
     for i in 0..<10 {
          print("🔷", i)
     }
}
// Main thread
for i in 20..<30 {
     print("⚪️", i)
}

Agar biz ushbu kodni ishga tushirsak, biz shunga o'xshash narsani ko'ramiz:

// prints: 🔷 0🔷 1🔷 2🔷 3🔷 4...⚪️ 20⚪️ 21⚪️ 22⚪️ 23⚪️ 24...

Bizning dasturimiz asosiy ish zarrachasida ishlayotgan for tsiklida to'xtaydi, shunda u sinxron bo'lgani uchun bizning navbatimizda kod blokini bajarishi mumkin.

Agar biz navbatni asinxronizatsiyaga o'zgartirsak, bizning ilovamiz asosiy oqimdagi kodni ishlatish uchun bepul bo'ladi va bir vaqtning o'zida bizning navbatimizdagi kod blokini ham bajaradi, shuning uchun biz shunga o'xshash narsani olamiz:

// prints: 🔷 0⚪️ 20🔷 1⚪️ 21🔷 2⚪️ 22🔷 3⚪️ 23🔷 4⚪️ 24🔷 ...

Garchi bizning asosiy mavzuimiz ilovamizdagi eng yuqori ustuvorlik bo'lsa-da, biz navbatimizning muhimligini ham ko'rsatishimiz va ilovamizga vazifalarimizni qanday qilib birinchi o'ringa qo'yish kerakligini bilishimiz mumkin. Ushbu spetsifikatsiya Xizmat sifati (QOS) deb nomlanadi. QOS - bu raqam va biz quyida keltirilgan qiymatlarni eng yuqori ustuvorlikdan eng pastgacha bo'lgan navbatlarimizga belgilashimiz mumkin.

.userInteractive
.userInitiated
.default
.utility
.background
.unspecified

Keling, buni sinab ko'raylik va ikkita navbatni qos ni o'zgartirish orqali solishtiramiz.

let firstQueue= DispatchQueue(label: "queue1", qos: DispatchQoS.userInitiated)
let secondQueue = DispatchQueue(label: "queue2", qos: DispatchQoS.userInitiated)
firstQueue.sync {
     for i in 0..<10 {
          print("🔷", i)
     }
}
secondQueue.sync {
    for i in 20..<30 {
         print("⚪️", i)
     }
}

Bu yerda biz navbatlarimizni bir xil darajadagi ustuvorlikka ega qilib qo‘ydik, shunda ilovamiz bir vaqtning o‘zida bu vazifalarni bajaradi.

// prints: ⚪️ 20🔷 0⚪️ 21🔷 1⚪️ 22🔷 2⚪️ 23🔷 3⚪️ 24🔷 4 ...

Agar siz secondQueue ning qos ni .background ga o'zgartirishga harakat qilsangiz, shunga o'xshash narsaga o'xshash juda boshqacha natijaga erishasiz:

// prints: 🔷 0🔷 1🔷 2🔷 3🔷 4...⚪️ 20⚪️ 21⚪️ 22⚪️ 23⚪️ 24...

Bizning firstQueue reytingimiz qos bo'yicha yuqoriroq darajaga ega, shuning uchun ilovamiz bu vazifani birinchi o'ringa qo'yadi va uning secondQueue dan oldin ishlashiga ishonch hosil qiladi.

Yuqorida biz sinab ko'rgan barcha navbatlar ketma-ket navbatlar deb nomlanadi. Bu navbatlar, agar biz boshqacha belgilamasak, unga berilgan har bir vazifani birin-ketin bajaradi. Agar biz vazifalarimizbir vaqtning o'zida bajarilishini istasak, ya'ni navbatlarimiz bir vaqtning o'zida turli vazifalarni bajarishini istasak, navbatimizni yaratishda ushbu atributni ko'rsatishimiz kerak bo'ladi.

Keling, ketma-ket navbatlarimizni ko'rib chiqaylik va bu safar biz unga ko'plab vazifalarni topshiramiz.

let randomQueue = DispatchQueue(label: "randomQueue", qos: .utility)

Odatiy bo'lib, navbatimiz ketma-ket bo'ladi, chunki biz uni bir vaqtda bo'lishini belgilamaganmiz.

randomQueue.async {
     for i in 0..<10 {
          print("🔷", i)
     }
}
randomQueue.async {
     for i in 20..<30 {
         print("⚪️", i)
     }
}
randomQueue.async {
     for i in 30..<40 { 
          print("🔶", i)
     }
}
// prints: 🔷 0🔷 1🔷 2🔷 3🔷 4...⚪️ 20⚪️ 21⚪️ 22⚪️ 23⚪️ 24...🔶 30🔶 31🔶 32🔶 33

Bu erda biz navbatimiz har bir vazifani birma-bir bajarayotganini ko'rishimiz mumkin.

Biroq, bir vaqtning o'zida navbatni bajarish uchun biz randomQueue qatoriga attribute qo'shamiz.

let randomQueue = DispatchQueue(label: "randomQueue", qos: .utility, attributes: .concurrent)

Agar biz biz ilovamizni ishga tushirsak, bizning vazifalarimiz endi parallel ishlayotganini sezamiz.

// prints: 🔹 0⚪️ 20🔶 30🔹 1⚪️ 21🔶 31🔹 2⚪️ 22🔶 32🔹 3⚪️ 23🔶 33...

Ilgari men maxsus navbatlar yaratish o‘rniga tizim bizgaglobaldeb nomlangan fon dispetcherlik navbatlarini taqdim etishini aytib o‘tgandim.

let globalQueue = DispatchQueue.global()
globalQueue.async {
     // Do something here
}

Global navbatlar xuddi biz maxsus navbatlardan foydalanganimizdek ishlatilishi mumkin, lekin ularni suiiste'mol qilmaslik kerak. Biz bu navbat bilan moslashtira olmaymiz, lekin biz har doim qos ni o'zgartirishimiz mumkin.

Global navbatlardan foydalanishdan tashqari, ehtiyojlarimizga qarab asosiy navbatga ham kirishimiz mumkin.

DispatchQueue.main.async {
     // Do something here
}

Asosiy navbatlar foydalanuvchi interfeysini yangilash va rasmlarimizni olish uchun juda mos keladi, boshqa har qanday og‘ir vazifa esa fonda bajarilishi kerak.

Umuman olganda, GCD bizga ilovalarimizda bir nechta vazifalarni bajarishga va ilovamizning muayyan kod bloklarini qanday bajarishini xohlashimizga qarab sinxron yoki asinxron, ketma-ket yoki bir vaqtda kodni ishga tushirish imkonini beradi. Biz maxsus navbatlarni yaratishimiz yoki ushbu turli vazifalarni bajarish uchun Apple-ning global navbatlaridan foydalanishimiz mumkin va asosiy mavzu har doim foydalanuvchi interfeysini yangilashga bag'ishlangan bo'lishi kerak.

Umid qilamanki, bu post foydali bo'ldi va quyida sharhlaringizni qoldiring!