Sobes.tech
Middle+

iOS'da deadlockning eng yorqin misoli nima bo'lishi mumkin?

sobes.tech AI

AIdan javob

iOS'da deadlock'ning eng aniq misoli, maxsus mexanizmlar ishlatilmasdan fon oqimidan UI ni yangilashga urinish paytida yuzaga keladi.

// Bu kod deadlock yoki xatolikni (iOS versiyasi va kontekstga qarab) keltirib chiqaradi
// asosiy oqimdan tashqarida chaqirilganda
DispatchQueue.global().async {
    // Orqa fon ishini bajarish...
    print("Orqa fon ish davom etmoqda")

    // UI ni to'g'ridan-to'g'ri fon oqimidan yangilashga urinish
    // Bu xato yoki deadlockga olib keladi, chunki UIKit iplararo xavfsiz emas
    DispatchQueue.main.syncが必要です!
    // Bu muammoni ko'rsatish uchun qo'shilgan, haqiqiy kodda bunday qilish mumkin emas!
    DispatchQueue.main.sync {
        // Asosiy oqimda belgi yangilashga urinish
        // Ammo biz allaqachon asosiy oqimga sinxron kutmoqdamiz, u bloklangan
        // o'zimizning sinxron yuborish blokimiz tomonidan, bu deadlockga olib keladi.
        print("UI ni yangilashga urinish")
        // someLabel.text = "Orqadan yangilandi" // Muammo yuzaga keladigan misol satr
    }
    print("Orqa fon ish yakunlandi")
}

Tushuntirish:

UIKit (iOS'da foydalanuvchi interfeysini yaratish uchun framework) iplararo xavfsiz emas. Barcha UI operatsiyalari faqat asosiy oqimda bajarilishi kerak.

Yuqoridagi misolda, DispatchQueue.main.sync { ... } blokini fon oqimidan chaqirsangiz:

  1. Fon oqimi bloklanadi va asosiy oqimning unga yuborilgan blokni bajarishini kutadi.
  2. Asosiy oqim band bo'lishi mumkin yoki, bu scenarioda, fon oqimidan boshlash kerak bo'lgan operatsiyaning yakunlanishini kutmoqda (garchi bu misolda shunday emas, sinxron yuborish fon oqimidan asosiy oqimga yuborish muammo).
  3. sync holatida, fon oqimi, asosiy oqim yuborgan blokni bajarishdan oldin tugata olmaydi. Agar asosiy oqim allaqachon bloklangan bo'lsa (masalan, fon oqimidagi operatsiyaning yakunlanishini kutayotgan bo'lsa, u ham asosiy oqimni kutmoqda yoki shunchaki band), bu tsiklik kutishni, ya'ni deadlockni yuzaga keltiradi.

To'g'ri yechim:

UI ni yangilash uchun asinxron yuborishni ishlatish.

// To'g'ri yechim: UI ni asinxron tarzda asosiy oqimda yangilash
DispatchQueue.global().async {
    // Orqa fon ishini bajarish...
    print("Orqa fon ish davom etmoqda")

    // UI yangilashni asinxron tarzda asosiy oqimga yuborish
    DispatchQueue.main.async {
        print("UI asosiy oqimda yangilanmoqda")
        // someLabel.text = "Orqadan yangilandi" // UI yangilash uchun to'g'ri joy
    }
    print("Orqa fon ish yakunlandi")
}

Bu yerda, fon oqimi, blokni asosiy oqimga yuborishda bloklanmaydi, bu esa fon vazifasi va asosiy oqimning mustaqil ishlashiga imkon beradi va deadlockdan qochadi.