ARC: bu nima, Automatic Reference Counting iOS da ishlash prinsipi

Muallif: IT Sectr Nashr etilgan: 2026-03-29 O'qish vaqti: 8 daq

Automatic Reference Counting (ARC) — Swift va Objective-C da xotirani boshqarish tizimi boʻib, har bir obyektga boʻgan referanslar sonini avtomatik hisoblaydi va hisoblagich nolga yetganda uni boʻhatadi. Apple Swift Documentation, 2026 maʻlumotlariga koʸra, ARC kompilyatorga oʻrnatilgan va kompilyatsiya bosqichida ishlaydi, kerakli joylarga retain/release chaqiruvlarini joylashtiradi. Garbage Collection dan farqli oʻlaroq, ARC alohida yigʻuvchi ipni talab qilmaydi va ilova ishlashi vaqtida pauzalar yaratmaydi.

Asosiy maʻlumotlar

  • ARC — Automatic Reference Counting, Swift va Objective-C da kompilyator xotira boshqaruv tizimi
  • Ishlash prinsipi — har bir obyektning referans hisoblagichi (retain count) bor, nolga tenglashganda obyekt darhol boʻshatiladi
  • Kvalifikatorlar — strong, weak va unowned referansning hisoblagichga va obyektning hayot aylanishiga qanday taʻsir qilishini aniqlaydi
  • GC dan farqi — ARC kompilyatsiya bosqichida deterministik ishlaydi, Stop-The-World pauzalari va fon yigʻuvchi ipsiz
  • Retain Cycle — ARC ning asosiy muammosi: agar ikki obyekt strong orqali bir-biriga havola qilsa, ularning hisoblagichi hech qachon nolga tushmaydi

ARC nima?

ARC (Automatic Reference Counting) — bu Apple tomonidan Xcode 4.2 (2011) da Objective-C uchun taqdim etilgan va Swift tomonidan meros qilib olingan kompilyator xotira boshqaruv mexanizmidir. Qoʻl bilan xotira boshqaruvidan (Manual Retain-Release, MRR) farqli oʻlaroq, ARC retain, release va autorelease chaqiruvlarini toʻliq avtomatlashtiradi, ularni kompilyatsiya bosqichida dasturchi ishtirokisiz joylashtiradi.

AR C garbage collector emas. Bu dinamik kod joylashtirish bilan statik tahlil: kompilyator obyektlarning umr muddatini tahlil qiladi va obyektlar yaratilgan, nusxalangan yoki koʻrinish doirasidan chiqqan nuqtalarda retain/release joylashtiradi. Natija — deterministik xotira boʻshatilishi: obyekt unga havolalar toʻxtaganda aynan oʻsha paytda, kechikishlar va pauzalarsiz oʻchiriladi.

WWDC 2011 Session 323 maʻlumotlariga koʸra, MRR dan ARC ga oʻtish Apple ilovalarida xotira bilan bogʻli crash-baglar sonini 70% ga kamaytirdi. Dasturchilar qoʻl bilan retain/release muvozanatini saqlashni toʻxtatdilar, bu butun bir sinf oqish va double-free xatolarini bartaraf etdi.

Automatic Reference Counting qanday ishlaydi

Xotiradagi har bir obyektning referans hisoblagichi (retain count) bor. Obyekt yaratilganda hisoblagich 1 ga oʻrnatiladi. Yangi strong-referans obyektga ishora qilganda — hisoblagich ortadi (retain). Strong-referans yoʻqolganda — hisoblagich kamayadi (release). Nolga yetganda obyekt darhol dealokatsiya qilinadi.

Swift kompilyatori retain/release ni har bir tayinlashda emas — optimallashtirish uchun statik tahlildan foydalanadi. Masalan, agar obyekt uzatilgandan keyin foydalanilmasligi kafolatlangan boʻlsa, kompilyator ortiqcha release/retain ni oʻtkazib yuborishi mumkin. Bu optimallashtirish ARC Optimisation deb ataladi.

swift
class Person {
    let name: String
    init(name: String) {
        self.name = name
        print("\(name) ishga tushirildi (retain count: 1)")
    }
    deinit {
        print("\(name) dealokatsiya qilindi")
    }
}

func testARC() {
    let p = Person(name: "Alice")  // retain count = 1
    let q = p                      // retain count = 2
    // q doiradan chiqadi
    // retain count = 1
    // p doiradan chiqadi
    // retain count = 0 → deinit
}

Ushbu misolda ARC hisoblagichni qanday boshqarishi koʻrinadi: q = p tayinlanganda hisoblagich ortadi, q doira dan chiqqanda — kamayadi. Oxirgi strong-referans yoʻqolganda deinitsializator darhol chaqiriladi. Hech qanday garbage collector kutmaydi — xotira darhol boʻshatiladi.

ARC vs Garbage Collection: asosiy farqlar

ARC va Garbage Collection bir xil vazifani — avtomatik xotira boshqaruvini — hal qiladi, lekin tubdan farqli yondashuvlar bilan. Ularning oʻrtasidagi tanlov til arxitekturasini belgilaydi: Swift (ARC) vs Java/Go (GC). Keling, asosiy farqlarni koʻrib chiqaylik.

XususiyatARC (Swift/ObjC)GC (Java/Go)
Boʻshatish momentiDeterministik: hisoblagich nolga tushganda darholNodeterministik: keyingi yigʻishda
Ijro pauzalariYoʻq (kompilyatsiya bosqichida retain/release qoʻshimchalari)Stop-The-World pauzalari bor (2–200 ms)
Qoʻshimcha yukHar bir referansda hisoblagichni oshirish/kamaytirishObyekt grafigini aylanib chiqish, belgilash, tozalash
MuammolarRetain Cycle (qoʻl bilan hal qilish)Heap fragmentatsiyasi, unutilgan referanslarda oqish
Qoʻshimcha ipTalab qilinmaydiGarbage collector ipi talab qilinadi

Asosiy kompromis: ARC obyektlarning bashorat qilinadigan umr muddatini va nol pauzalarni taʻminlaydi, lekin dasturchidan retain cycle tushunchasini va toʻgʻri weak/unowned tanlashni talab qiladi. GC bu tashvishlardan xalos qiladi, ammo nodeterministik pauzalar va qoʻshimcha ip evaziga.

Strong, Weak va Unowned: ARC da referans kvalifikatorlari

ARC uch turdagi referans kvalifikatorini belgilaydi, ularning har biri hisoblagichga va obyektning hayot aylanishiga turlicha taʻsir qiladi. Kvalifikatorni toʻgʻri tanlash Swift da xavfsiz xotira bilan ishlashning asosidir.

Strong

Strong — standart kvalifikator. Har bir strong-referans obyektning retain count ini 1 ga oshiradi. Hech boʻlmaganda bitta strong-referans mavjud ekan, obyekt tirik. Swift dagi barcha sinf xususiyatlari va lokal oʻzgaruvchilar standart holda strong dir. Strong-referanslar egalik munosabatini yaratadi: A obyekti B obyektiga ega.

Weak

Weak — retain count ni oshirmaydigan referans. Obyekt weak-referans unga ishora qilsa ham dealokatsiya qilinishi mumkin. Dealokatsiyadan keyin weak-referans avtomatik ravishda nil ga oʻrnatiladi. Weak-referanslar har doim ixtiyoriy tip bilan (?) var sifatida eʻlon qilinadi. Ular retain cycle ni buzish uchun, ayniqsa delegate namunasida ishlatiladi.

Unowned

Unowned — weak kabi retain count ni oshirmaydigan egasiz referans. Biroq unowned-referans dealokatsiyadan keyin nil ga oʻrnatilmaydi — boʻshatilgan obyektga murojaat crash ga sabab boʻladi. Unowned obyektning referans qiluvchi obyektdan kamida shuncha yashashi kafolatlanganida ishlatiladi. Tipik stsenariy — yopilishlar (closures) va kafolatlangan umr muddati bilan ota-bola munosabatlari.

swift
class Customer {
    let name: String
    var card: CreditCard?         // strong
    init(name: String) { self.name = name }
    deinit { print("\(name) dealokatsiya qilindi") }
}

class CreditCard {
    let number: String
    unowned let customer: Customer   // unowned — ega emas
    init(number: String, customer: Customer) {
        self.number = number
        self.customer = customer
    }
    deinit { print("Karta \(number) dealokatsiya qilindi") }
}

var customer: Customer? = Customer(name: "Bob")
customer?.card = CreditCard(number: "1234", customer: customer!)
customer = nil
// Customer va CreditCard ikkalasi ham boʻshatildi — retain cycle yoʻq

Bu yerda CreditCard Customer ga unowned-referansdan foydalanadi. Customer kartaga ega (strong), karta esa mijozga ega emas (unowned). Customer nil boʻlganda ikkala obyekt ham boʻshatiladi — retain cycle yuz bermaydi. Agar card.customer strong boʻlganida, sikl boʻshatishni bloklagan boʻlardi.

ARC ning tipik muammolari va ularni hal qilish

Avtomatlashtirishga qaramay, ARC panatseya emas. Dasturchilar xotira boshqaruvining ichki mexanizmini tushunishni talab qiladigan bir necha tipik muammolarga duch kelishadi.

Yopilishlarda Retain Cycle

Swift dagi yopilishlar (closures) tashqi oʻzgaruvchilarni strong-referans orqali tutib oladi. Agar yopilish sinf xususiyatiga tayinlansa va self ni tutib olsa — retain cycle yuzaga keladi: sinf yopilishni, yopilish self ni ushlab turadi. Yechim — weak yoki unowned bilan capture list.

swift
class NetworkManager {
    var completionHandler: ((Data?) -> Void)?
    var data: Data?

    func fetchData() {
        completionHandler = { [weak self] result in
            guard let self else { return }
            self.data = result
            self.processResult()
        }
    }

    func processResult() { }
}

Capture list [weak self] yopilish ichida self ga weak-referans yaratadi. Bu potensial retain cycle ni buzadi. Guard let self kodni bajarishdan oldin obyektning tirikligini kafolatlaydi. weak self — Swift da asinxron yopilishlar uchun standart amaliyot.

Retain/Release unumdorligi

Retain/release yengil operatsiyalar boʻlsada, qaynoq sikllarda tez-tez hisoblagichni oshirish/kamaytirish qoʻshimcha yuk hosil qiladi. Swift 5.9+ da kompilyator optimallashtirish dan foydalanadi, bunda tahlilchi xavfsizlikni isbotlasa, ortiqcha retain/release lar olib tashlanadi. Biroq Objective-C da retain/release sekundiga millionlab chaqiruvlar bilan yuqori yuklangan stsenariylarda hali ham tor boʻgʻz boʻlishi mumkin.

Autorelease Pool

Autorelease Pool — Objective-C va Swift ning baʻzi stsenariylarida ishlatiladigan kechiktirilgan release mexanizmi. Obyektlar hovuzga joylashtiriladi va hovuz toʻkilganda release oladi. Koʻp sonli vaqtinchalik obyektlari boʻlgan sikllarda (masalan, JSON tahlil qilish) oʻz autoreleasepool yaratish operativ xotiraning eng yuqori isteʻmolini kamaytiradi.

Tez-tez soʻraladigan savollar

ARC qoʻl bilan xotira boshqaruvidan (MRR) qanday farq qiladi?

Qoʻl bilan boshqarishda (MRR) dasturchi aniq retain, release va autorelease ni chaqirardi. ARC bu chaqiruvlarni kompilyatsiya bosqichida avtomatik joylashtiradi, double-free xavfini, unutilgan release tufayli oqishlarni va retain/release muvozanat xatolarini bartaraf etadi.

ARC C/C++ kodi bilan ishlay oladimi?

ARC faqat Objective-C obyektlari va Swift class larini boshqaradi. C/C++ tuzilmalari va koʻrsatkichlari uchun ARC qoʻlanilmaydi — bu obyektlar qoʻl bilan yoki C++ aqlli koʻrsatkichlari (shared_ptr, unique_ptr) orqali boshqariladi. Core Foundation obyektlari (CFString, CGColor) ham ARC ga kirmaydi.

Qachon weak va qachon unowned ishlatish kerak?

weak — obyekt havola qiluvchidan oldin dealokatsiya qilinishi mumkin boʻlganda (delegatlar, asinxron yopilishlar). unowned — obyekt havola qiluvchidan kam boʻlmagan holda yashashi kafolatlanganida (ota-bola, bunda bola otasiz mavjud boʻla olmaydi). Agar ishonchingiz komil boʻlmasa — weak ni tanlang.

Ekzistensial tiplar nima va ular ARC ga qanday taʻsir qiladi?

Swift dagi ekzistensial tiplar (protocol as type) qiymatni maxsus konteynerga (existential container) joylaydi. Bu protokol chegaralarida retain/release sonini oshiradi. Swift 5.7+ da opaque result types va some parametrlari konteynerni bartaraf etib, qoʻshimcha yukni kamaytiradi.

Swift da retain count ni qanday tekshirish mumkin?

Swift da retain count ni oʻqish uchun toʻgʻridan-toʻgʻri API yoʻq — bu amalga oshirish detali hisoblanadi. Diagnostika uchun Xcode da Instruments (Allocations, Leaks) yoki Memory Debugger dan foydalaning. Bu vositalar sinfning tirik instansiyalari sonini va ushlab turish zanjirini koʻrsatadi.

Xulosa

  • ARC — referanslarni hisoblash orqali ishlaydigan Swift va Objective-C uchun kompilyator xotira boshqaruv tizimi
  • Prinsip — har bir obyektning retain count i bor; nolga tushganda obyekt darhol va deterministik ravishda boʻshatiladi
  • GC dan farqi — ARC fon ipi va Stop-The-World pauzalarisiz ishlaydi, lekin retain cycle nazoratini talab qiladi
  • Strong — hisoblagichni oshiradi; weak va unowned — oshirmaydi, lekin unowned dealokatsiyada nolga tushmaydi
  • Yopilishlar — Swift da retain cycle ning asosiy sababi; capture list [weak self] — standart yechim
  • Autorelease Pool — sikllar va maxsus stsenariylarda vaqtinchalik obyektlar uchun kechiktirilgan boʻshatish mexanizmi
  • Diagnostika — Xcode Memory Debugger, Instruments va LeakCanary (ObjC bridge orqali) muammolarni topish uchun

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