Strong Reference (kuchli havola): bu nima, ishlash mexanizmi va ARC

Muallif: IT Sectr Nashr etilgan: 2026-03-30 O'qish vaqti: 9 daq

Strong Reference (kuchli havola) — bu ob'ekt xotirada kamida bitta faol havola mavjud ekan, u yerda qolishini ta'minlovchi standart xotira boshqaruvi mexanizmidir. Kuchsiz havolalardan farqli o'laroq, kuchli havola ob'ektning havolalar hisoblagichini oshiradi va uning avtomatik bo'shatilishining oldini oladi. Apple Developer Documentation ma'lumotlariga ko'ra, ARC Swift va Objective-C da ob'ektlarning hayot davrini avtomatik boshqaradi. Kuchli havolalar ishini tushunish mobil ilovalarda xotira oqishlari va siklik bog'liqliklarning oldini olish uchun muhim ahamiyatga ega.

Asosiy fikrlar

  • Strong Reference — ob'ektni xotirada ushlab turadigan, uning retain count-ni 1 ga oshiradigan havola.
  • ARC Swift va Objective-C da qo'lda xotira boshqaruvini bartaraf etib, avtomatik ravishda release va retain operatsiyalarini kiritadi.
  • Retain cycle ikki ob'ekt bir-biriga kuchli havolalar orqali murojaat qilganda yuzaga keladi — xotira hech qachon bo'shatilmaydi.
  • Weak Reference havolalar hisoblagichini oshirmaydi va ob'ekt bo'shatilganda avtomatik nolga tushadi.
  • Unowned Reference hisoblagichni oshirmaydi, lekin ob'ekt egasidan uzoq yashamasligini taxmin qiladi.

Strong Reference nima?

Strong Reference — bu axlat yig'uvchi yoki xotira boshqaruvi tizimi tomonidan ob'ektning yo'q qilinishining oldini oladigan havola turidir. Ob'ektga kamida bitta kuchli havola mavjud ekan, uning ostidagi xotira bo'shatilmaydi. Bu Swift va Objective-C da ARC va Java va Kotlin da garbage collection asosida yotadigan asosiy mexanizmdir.

Kuchli havola tushunchasi avtomatik xotira boshqaruviga ega barcha tillar uchun fundamentaldir. ARC li tizimlarda har bir kuchli havola ob'ektning havolalar hisoblagichini oshiradi. Hisoblagich nolga tushganda, ob'ekt darhol dealokatsiya qilinadi. Java va Kotlin da axlat yig'uvchi bilan kuchli havola ob'ektning erishish mumkinligini va GC tomonidan yig'ilmasligini kafolatlaydi.

WWDC 2021 ma'lumotlariga ko'ra, iOS ilovalaridagi xotira oqishlarining taxminan 35% kuchli havolalarning noto'g'ri ishlatilishi va ushlab turish sikllari bilan bog'liq. Android ishlanmasida yopilishlar va chaqiruvlardagi yashirin strong reference orqali oqishlar Context Leak dan keyin xotira muammolarining ikkinchi eng keng tarqalgan sababidir.

Xotira bilan samarali ishlash uchun strong, weak va unowned havolalar orasidagi farqni tushunish va ob'ektlarning egaligi va hayot davriga qarab havola turini to'g'ri tanlash kerak.

ARC xotira boshqaruviga yondashuvni qanday o'zgartirdi

ARC joriy etilishidan oldin ishlab chiquvchilar har bir ob'ekt uchun qo'lda retain va release chaqirishardi, bu ko'plab xatolarga olib kelardi. Apple tomonidan 2011 yilda LLVM 3.0 chiqarilishi bilan taqdim etilgan ARC, kompilyatsiya bosqichida egalik grafigini tahlil qilib, bu jarayonni avtomatlashtirdi. Kompilyatorning o'zi retain, release va autorelease chaqiruvlarini kerakli joylarga kiritadi.

Clang Static Analyzer ga ko'ra, ARC ning joriy etilishi iOS ilovalaridagi xotira bilan bog'liq xatolar sonini 70% ga kamaytirdi. Ishlab chiquvchi uchun bu xotira boshqaruvi xavfsizroq bo'lganini, lekin shu bilan birga retain cycles dan qochish uchun kuchli havolalarning qanday ishlashini tushunish zaruriyati paydo bo'lganini anglatadi.

Kotlin va Java da ARC rolini axlat yig'uvchi bajaradi, lekin kuchli havola printsipi bir xil qoladi: GC Roots — bu ob'ektlar kuchli havolalar bilan ushlab turiladigan kirish nuqtalaridir. Ob'ekt GC Root dan kuchli havolalar zanjiri orqali erishish mumkin bo'lsa, u yig'ilmaydi.

Strong Reference ARC da qanday ishlaydi?

ARC (Automatic Reference Counting) yig'indagi har bir ob'ekt uchun havolalarni hisoblash printsipi bilan ishlaydi. Ob'ektga yangi kuchli havola yaratilganda, hisoblagich ortadi (retain). Havola yo'q qilinganda yoki qayta yozilganda, hisoblagich kamayadi (release). Hisoblagich nolga yetganda, ob'ekt darhol xotiradan o'chiriladi.

Swift da bir misolni ko'rib chiqaylik. Sinf namunasi yaratilganda, ARC xotira ajratadi va retain count ni 1 ga teng qiladi. Har bir yangi o'zgaruvchiga tayinlash hisoblagichni oshiradi. O'zgaruvchi ko'rinish sohasidan chiqqanda, hisoblagich kamayadi:

swift
class ProfileViewController {
    var nameLabel: String?
    var avatarImage: UIImage?

    func loadProfile() {
        // retain count = 1 yangi namuna uchun
        let user = User(name: "Ivan")
        // retain count = 2 nameLabel tayinlangandan keyin
        nameLabel = user.name
        // metoddan chiqish — user scope dan chiqadi, retain count = 1
    }
}

Bu kodda ARC User ob'ekti kamida bitta kuchli havola mavjud ekan, xotirada qolishini kafolatlaydi. loadProfile funksiyasi tugaganda, mahalliy user o'zgaruvchisi yo'q qilinadi, lekin nameLabel hali ham ob'ektni ushlab turadi. Xotira faqat nameLabel mavjud bo'lishni to'xtatganda yoki qayta yozilganda bo'shatiladi.

Kotlin da o'xshash xatti-harakat GC Roots orqali ta'minlanadi. Axlat yig'uvchining ildizidan (masalan, statik maydon yoki faol thread) kuzatilishi mumkin bo'lgan strong references zanjiri mavjud ekan, ob'ekt xotirada qoladi. Farqi shundaki, GC xotirani darhol bo'shatmaydi — bu erishish mumkinligini tahlil qilgandan keyin asinxron ravishda sodir bo'ladi.

Xotira qachon bo'shatiladi

ARC da bo'shatish hisoblagich nolga tushganda sinxron ravishda sodir bo'ladi. Swift va Objective-C da ob'ekt qachon o'chirilishini aniq bilasiz. Kotlin va Java da bo'shatish momenti oldindan aytib bo'lmaydi, lekin bu axlat yig'uvchi darajasida siklik bog'liqliklarni aniqlashning yanada moslashuvchan sxemasi bilan kompensatsiya qilinadi.

Retain Cycles va xotira oqishlari

Retain cycle (ushlab turish sikli) — ikki yoki undan ortiq ob'ekt bir-biriga o'zaro kuchli havolalarga ega bo'lgan vaziyatdir. Natijada ularning retain count hech qachon nolga tushmaydi va ob'ektlar ilova uchun keraksiz bo'lib qolgandan keyin ham xotira bo'shatilmaydi.

Klassik misol: ota view controller bola ob'ektni kuchli havola bilan ushlab turadi, u esa o'z navbatida otani kuchli havola bilan ushlab turadi. Bu delegatlar, yopilishlar va ichma-ich lambda ifodalari bo'lgan vaziyatlar uchun xosdir. Instruments Leaks ma'lumotlariga ko'ra, retain cycles ARC dan foydalanadigan ilovalardagi barcha xotira oqishlarining 60% gacha qismini tashkil qiladi.

swift
class ParentViewController: UIViewController {
    var child: ChildViewController?

    func setupChild() {
        child = ChildViewController()
        // retain cycle: parent child ni ushlab turadi, child parent ni closure orqali ushlab turadi
        child?.onEvent = {
            self.handleEvent()
        }
    }

    func handleEvent() {}
}

Muammo shundaki, onEvent yopilishi self (ParentViewController) ni kuchli havola bilan ushlaydi va ParentViewController child ni kuchli havola bilan ushlab turadi. Ikkala ob'ekt hech qachon bo'shatilmaydi. Yechim — siklni uzish uchun yopilishda weak self dan foydalanish.

Kotlin da o'xshash sikllar tashqi ob'ektlarni ushlaydigan lambdalardan foydalanganda yuzaga keladi. JVM axlat yig'uvchi vaqt o'tishi bilan bunday sikllarni aniqlashi mumkin, lekin faqat ob'ektlar GC Roots dan erishib bo'lmaydigan bo'lsa. Agar sikl faol thread yoki UI konteksti bilan bog'liq bo'lsa, oqish ilovaning butun hayoti davomida qoladi.

Strong vs Weak vs Unowned Reference

Havola turlari orasidagi farqni tushunish — xavfsiz xotira boshqaruvining kalitidir. Strong Reference retain count ni oshiradi. Weak Reference retain count ni oshirmaydi va ob'ekt bo'shatilganda avtomatik nil bo'ladi. Unowned Reference ham retain count ni oshirmaydi, lekin nolga tushmaydi — bo'shatilgandan keyin unga murojaat qilish crash ga olib keladi.

Havola turiRetain countXavfsizlikQachon ishlatish
Strong+1Xavfsiz (standart)Ob'ektga egalik, parent → child munosabati
WeakO'zgartirmaydiAvtomatik nolga tushish (safe)Delegatlar, callback, qayta havolalar
UnownedO'zgartirmaydiKech murojaat qilishda crash xavfiOb'ekt egasidan uzoq yashamasligi kafolatlanganida

Havola turini tanlash egalik munosabati bilan belgilanadi. Agar B ob'ekti A ning qismi bo'lsa va usiz mavjud bo'lolmasa — Strong dan foydalaning. Agar B mustaqil mavjud bo'la olsa va xabarlar uchun A ga murojaat qilsa — Weak dan foydalaning. Unowned kamdan-kam qo'llaniladi — faqat bola ob'ektning hayoti ota hayotidan qat'iy oshmaganda.

Tanlash uchun amaliy qoida

Apple Developer Documentation tavsiya qiladi: standart sifatida barcha egalik munosabatlari uchun strong dan foydalaning. Retain cycle dan qochish kerak bo'lsa — qaysi havola kuchsiz bo'lishi kerakligini aniqlang. Odatda bu iyerarxiyadagi qayta havoladir (child → parent). Kotlin da o'xshash rol kesh va observer na'munalari uchun qo'llaniladigan java.lang.ref dan WeakReference ga tegishli.

Kuchli havola muammolarini qanday tuzatish kerak

Retain cycles ni aniqlash — birinchi qadam. Ikkinchisi — ularni to'g'ri bartaraf etish. Kuchli havola sikllariga qarshi kurashning asosiy vositasi havolalardan birini weak yoki unowned bilan almashtirishdir. Axlat yig'ishga ega tillarda qo'shimcha ravishda har bir kirishdan oldin qo'lda null tekshiruvi bilan WeakReference qo'llaniladi.

Swift va Objective-C da eng keng tarqalgan tuzatish yopilishlarga [weak self] qo'shishdir. Bu yopilish ob'ektni bo'shatilgandan keyin ushlab turmasligini kafolatlaydi. Kotlin da o'xshash maqsadlar uchun WeakReference o'rami yoki onDestroy da havolani aniq tozalash ishlatiladi.

swift
class NetworkService {
    func fetchData(completion: @escaping (Data?) -> Void) {
        // weak self orqali ushlash — retain cycle istisno qilingan
        URLSession.shared.dataTask(
            with: URL(string: "https://api.example.com")!
        ) { [weak self] data, response, error in
            guard let self else { return }
            completion(data)
        }.resume()
    }
}

Bu misolda [weak self] NetworkService endi kerak bo'lmagandan keyin yopilish tomonidan ushlab turilmasligini kafolatlaydi. Agar self so'rov tugashidan oldin bo'shatilgan bo'lsa — guard let self else { return } completion ni chaqirmasdan yopilishdan chiqadi.

Retain cycles diagnostikasi uchun iOS uchun Instruments Leaks yoki Android uchun Android Profiler + LeakCanary dan foydalaning. Bu vositalar aniq ushlab turish grafigini ko'rsatadi va ob'ektning bo'shatilishiga qaysi kuchli havola to'sqinlik qilayotganini bildiradi. Muntazam xotira profillash har bir mobil loyihaning CI/CD pipeline qismi bo'lishi kerak.

Swift va Kotlin da Strong Reference — taqqoslash

Swift va Kotlin tubdan farqli xotira boshqaruvi mexanizmlaridan foydalanadi, lekin kuchli havola tushunchasi ikkalasida ham mavjud. Swift da retain count = 0 bo'lganda sinxron bo'shatish bilan ARC qo'llaniladi. Kotlin da erishib bo'lmaydigan ob'ektlarni asinxron tozalaydigan kuzatuvchi GC ishlatiladi.

ParametrSwift (ARC)Kotlin (JVM GC)
MexanizmHavolalarni hisoblash (retain count)Erishish mumkinligini kuzatish (GC Roots)
Bo'shatishSinxron (hisoblagich nolga tushganda)Asinxron (GC sikli bo'yicha)
Retain cycleAvtomatik aniqlanmaydiGC aniqlashi mumkin, lekin darhol emas
Weak refweak (avtomatik nolga tushish)WeakReference (qo'lda tekshirish)

Asosiy amaliy farq: Swift da retain cycle — kafolatlangan oqishdir. Kotlin da GC ob'ektlar ildizdan erishib bo'lmaydigan bo'lsa, siklni uzishi mumkin, lekin oqib chiqqan ob'ektlarning hayoti oldindan aytib bo'lmaydigan bo'lib qoladi. Shuning uchun ikkala tilda eng yaxshi strategiya — loyihalash bosqichida kuchli havola sikllaridan qochishdir.

Swift uchun delegate na'munalarida va yopilishlarda weak dan foydalaning. Kotlin uchun — WeakReference yoki egasi yo'q qilinganda havolalarni avtomatik tozalaydigan Lifecycle-aware komponentlar. Ikkala yondashuvda maqsad bir xil — uzilmas ushlab turish zanjirini yaratadigan joylarda kuchli havolalarni istisno qilish.

Ko'p beriladigan savollar

Strong Reference Weak Reference dan nima bilan farq qiladi?

Strong Reference ob'ektning retain count ni oshiradi va havola mavjud ekan, uning bo'shatilishining oldini oladi. Weak Reference retain count ni o'zgartirmaydi va ob'ekt xotiradan o'chirilganda avtomatik nolga tushadi. Kuchli havolalar egalik uchun, kuchsiz havolalar esa qayta bog'lanishlar va delegatlar uchun ishlatiladi.

Retain cycle nima va nima uchun xavfli?

Retain cycle — ikki ob'ekt bir-birini kuchli havolalar bilan ushlab turadigan o'zaro blokirovkadir. Ularning retain count hech qachon nolga tushmaydi, xotira bo'shatilmaydi. Bu xotira oqishiga olib keladi: ob'ektlar abadiy yig'inda qoladi, ilova tobora ko'proq resurslarni iste'mol qiladi va oxirida OutOfMemory bilan qulab tushadi.

iOS ilovasida retain cycle ni qanday aniqlash mumkin?

Xcode dan Instruments Leaks dan foydalaning — Leaks shabloni bilan profillashni boshlang, ilovada stsenariyni bajaring va oqish ko'rsatkichlarini tekshiring. Aniq diagnostika uchun Cycles & Roots yorlig'iga o'ting — u uzilmas sikl hosil qiluvchi o'zaro strong reference grafigini ko'rsatadi.

Qachon Weak o'rniga Unowned ishlatilishi kerak?

Unowned ni bola ob'ektning hayoti ota hayotidan albatta oshmaganda qo'llang — masalan, ob'ektni qat'iy belgilangan doiraga bog'lashda. Agar shubha bo'lsa, Weak dan foydalaning, chunki bo'shatilgan unowned ga murojaat qilish ilovaning qulashiga sabab bo'ladi.

Kuchli havolalar ilova ishlashiga ta'sir qiladimi?

Bilvosita — ha. ARC dagi har bir retain va release qo'shimcha xarajatlarga ega atomik operatsiyadir. Sikllarda ko'p sonli ob'ektlar bo'lganda bu ishlashga ta'sir qilishi mumkin. Biroq asosiy muammo ARC ning ishlash tezligi emas, balki noto'g'ri tanlangan havola turi tufayli xotira oqishlaridir.

Xulosa

  • Strong Reference — ob'ektga egalikning asosiy mexanizmi, uni retain count ni oshirish orqali xotirada ushlab turadi.
  • ARC Swift va Objective C da xotira boshqaruvini avtomatlashtiradi, qo'lda retain va release ni yo'q qiladi, lekin retain cycles dan himoya qilmaydi.
  • Retain cycle o'zaro kuchli havolalar paytida yuzaga keladi — bu ARC tizimlarida xotira oqishlarining asosiy sababidir.
  • Weak va Unowned havolalar retain count ni oshirmasdan kuchli havola sikllarini uzadi.
  • Havola turini tanlash egalik munosabati bilan belgilanadi: parent→child uchun Strong, child→parent uchun Weak yoki Unowned.
  • Instruments Leaks va LeakCanary — iOS va Android da muammoli kuchli havolalarni aniqlash uchun asosiy vositalar.
  • Egalik grafigini oldindan loyihalang — bu ilova chiqarilgandan keyin xotira oqishlarini tuzatishdan arzonroq.

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing