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) — 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.
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.
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 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.
| Xususiyat | ARC (Swift/ObjC) | GC (Java/Go) |
|---|---|---|
| Boʻshatish momenti | Deterministik: hisoblagich nolga tushganda darhol | Nodeterministik: keyingi yigʻishda |
| Ijro pauzalari | Yoʻq (kompilyatsiya bosqichida retain/release qoʻshimchalari) | Stop-The-World pauzalari bor (2–200 ms) |
| Qoʻshimcha yuk | Har bir referansda hisoblagichni oshirish/kamaytirish | Obyekt grafigini aylanib chiqish, belgilash, tozalash |
| Muammolar | Retain Cycle (qoʻl bilan hal qilish) | Heap fragmentatsiyasi, unutilgan referanslarda oqish |
| Qoʻshimcha ip | Talab qilinmaydi | Garbage 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.
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 — 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 — 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 — 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.
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.
Avtomatlashtirishga qaramay, ARC panatseya emas. Dasturchilar xotira boshqaruvining ichki mexanizmini tushunishni talab qiladigan bir necha tipik muammolarga duch kelishadi.
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.
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 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 — 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
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 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.
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.
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 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
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.