Sobes.tech
Middle+

iOS dasturlashda run loop qachon ishlatiladi?

sobes.tech AI

AIdan javob

Run loop, odatda, foydalaniladi, agar siz oqimning xulq-atvorini boshqarish, uni voqea kutishga va mos kodni bajarishga imkon berish uchun, uning vazifasini bajarib bo'lgach darhol tugashining oldini olish uchun. Bu quyidagilar uchun juda muhim:

  1. Asosiy oqim (Main Thread): Asosiy oqimning run loopi UIKit/AppKit bilan o'zaro ta'sir, foydalanuvchi voqealari (touchlar, kliklar), vaqt o'lchovlari, tarmoq voqealari va performSelector:withObject:afterDelay: chaqiriqlarini boshqaradi. Uning bo'lmasligi, ilovaning foydalanuvchi harakatlariga javob berishini va UI-ni yangilashini ta'minlamaydi.

  2. Ikkinchi darajali oqimlar: Fon oqimi asinxron vazifalarni bajarishi, kiruvchi ma'lumotlarni (masalan, soketlar) tinglashi, boshqa oqimlardan xabarlarni qayta ishlashi yoki vaqt o'lchovchilaridan foydalanishi kerak bo'lsa. Tipik holatlar:

    • Soketlar bilan ishlash.
    • Vaqt o'lchovchi yordamida takroriy vazifalarni bajarish.
    • IPC (Inter-Process Communication) xabarlarini qabul qilish va qayta ishlash.
    • Kelajakdagi so'rovlarni bajarish uchun oqimni faol saqlash, uni doimiy ravishda yaratish va yo'q qilish o'rniga.

Ikkinchi darajali oqimda run loopdan foydalanish misoli, tarmoq ulanishini saqlash bo'lishi mumkin:

// Swiftda misol
class NetworkManager {
    private let networkThread = Thread {
        // Tarmoq sessiyasini, soketlarni va boshqalarni boshlash kodi

        // Voqealar manbaini (masalan, soket yoki port) run loopga qo'shish
        // CFRunLoopAddSource(CFRunLoopGetCurrent(), source, CFRunLoopMode.defaultMode)

        // Agar kerak bo'lsa, vaqt o'lchovchini qo'shish
        // CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.defaultMode)

        // Run loopni ishga tushirish. Bu voqea kelguncha oqimni bloklaydi.
        // .distantFuture - shunda run loop darhol tugamaydi
        RunLoop.current.run()

        // Run loop tugagach, tozalash kodi
        print("Tarmoq oqimi yakunlandi")
    }

    func start() {
        // `start()` ni `detachNewThreadSelector` o'rniga ishlatish
        // zamonaviy yondashuv
        networkThread.start()
    }

    // Boshqa oqimdan run loopni to'xtatish uchun metod
    func stop() {
        // Run loopga tugash haqida signal berish
        // CFRunLoopStop(CFRunLoopGetCurrent()) // yoki uni boshqarish uchun maxsus voqea qo'shish
        // Run loop odatda, voqealar manbai qolmaganda yoki to'g'ridan-to'g'ri stop chaqirilganda tugaydi
    }
}

Run loop bir vazifa bajarib, keyin tugaydigan oqimlar uchun kerak emas (masalan, DispatchQueue.global().async yordamida bajariladigan bir martalik fon operatsiyalari). Bu holda, Grand Central Dispatch (GCD) kifoya qiladi.