Unowned Reference (egasiz referans) — Swift-da retain count-ni oshirmaydigan va weak-dan farqli ravishda, obyekt ozod qilingandan keyin nil-ga o‘rnatilmaydigan egalik qilmaydigan referansdir. Apple Swift Language Guide, 2026-ga ko‘ra, unowned obyektning hech bo‘lmaganda unga murojaat qilayotgan obyekt qadar yashashi kafolatlanganida qo‘llaniladi. Weak Reference-dan farqli ravishda, unowned unwrap talab qilmaydi — bu non-optional tur, kodni tozaroq qiladi, lekin dasturchiga hayot davomiyligi kafolati uchun javobgarlik yuklaydi.
Asosiy fikrlar
Unowned Reference — ARC-da retain count-ni oshirmaydigan egalik qilmaydigan obyekt referansidir. Weak-dan farqli ravishda, unowned deallokatsiyadan keyin nollanmaydi: u allaqachon ozod qilingan xotira maydoniga ishora qilishda davom etadi. Bunday referansga murojaat EXC_BAD_ACCESS bilan runtime crash-ga sabab bo‘ladi.
“Egasiz” termini semantikani aks ettiradi: obyekt mavjud, lekin hech kim uning hayot davomiyligi uchun javobgar emas. Dasturchi ochiq bayon qiladi: “men kafolat beramanki, bu obyekt men unga murojaat qilayotganimda yashaydi”. Kompilyator bu kafolatni tekshirmaydi — bu dasturchi darajasida kontraktdir.
Swift.org Documentation, 2026-ga ko‘ra, unowned referanslar kafolatlangan hayot davomiyligi bo‘lgan ssenariylarda weak-dan afzal, chunki: ular opsional tur talab qilmaydi (toza kod), unwrap talab qilmaydi (kamroq force-unwrap yoki guard let) va zeroing weak-jadvalini yuritish uchun qo‘shimcha yuklamaga ega emas. Biroq, kontraktning har qanday buzilishi — crash.
Swift-da unowned referanslar let yoki var oldidan unowned kalit so‘zi bilan e’lon qilinadi. Weak-dan farqli ravishda, unowned ham let, ham var bo‘lishi mumkin va opsional turni talab qilmaydi. Bu xususiyat unowned-ni domen mantiqiga ko‘ra nil bo‘la olmaydigan referanslar uchun qulay qiladi.
class Country {
let name: String
var capital: City! // initsializatsiyadan keyin o'rnatiladi
init(name: String) { self.name = name }
}
class City {
let name: String
unowned let country: Country // unowned let — hayot kafolati
init(name: String, country: Country) {
self.name = name
self.country = country
}
}
// Foydalanish
let france = Country(name: "France")
let paris = City(name: "Paris", country: france)
france.capital = paris
// Country → City (strong), City → Country (unowned) — retain cycle yo'q
Bu misolda City unowned let country — shahar davlatsiz mavjud bo‘la olmaydi. Agar davlat yo‘qolsa, shahar (va referans) ma’nosini yo‘qotadi. Semantik jihatdan bu unowned uchun ideal holat: hayot davomiyligi kafolati mavjud, optional kerak emas, retain cycle yuzaga kelmaydi.
unowned var ruxsat etilgan, lekin kamroq uchraydi. Referans almashtirilishi mumkin bo‘lgan hollarda qo‘llaniladi (masalan, bolani boshqa ota-onaga bog‘lash). Almashtirishda eski obyektni ozod qilish — tashqi egasining javobgarligi.
Swift 5.0+ da unowned optional qo‘llab-quvvatlandi (unowned let x: Type?). Bu murosadir: unowned kafolat beradiki, agar referans nil bo‘lmasa, obyekt tirik. Ozod qilishdagi xatti-harakat — oddiy unowned kabi crash.
Unowned va weak o‘rtasidagi tanlov — Swift arxitekturasini loyihalashdagi tez-tez uchraydigan qarorlardan biri. Har bir holat uchun mezonlar va tavsiyalarni ko‘rib chiqaylik.
| Mezon | Weak | Unowned |
|---|---|---|
| Optional | Ha (Type?) | Yo‘q (Type) |
| Deallokatsiyada nollash | Avtomatik nil | Yo‘q (osilib qolgan ko‘rsatkich xavfi) |
| Tur (let/var) | Faqat var | let yoki var |
| Unumdorlik | Weak-jadvalga qo‘shimcha yuk | Minimal (oddiy ko‘rsatkich) |
| Xavfsizlik | Xavfsiz (nil tekshiriladi) | EXC_BAD_ACCESS xavfi |
| Hayot davomiyligi kafolati | Talab qilinmaydi | Ochiq kafolat talab qilinadi |
Obyektning hayot davomiyligiga eng kichik shubha bo‘lsa, weak-dan foydalaning. Weak xavfsiz, tushunarli va isbot talab qilmaydi. Unowned-dan foydalaning faqat obyektni oldinroq ozod qilish mumkin bo‘lgan barcha ssenariylarni istisno qilganingizda. Odatiy holatlar: ota-onasiz mavjud bo‘lmagan bola; sinxron bajariladigan kleyens; obyektni uning init metodi doirasida murojaat qilish.
Airbnb Swift Style Guide, 2025-ga ko‘ra, katta kod bazalarida sukut bo‘yicha weak-dan foydalanish, unowned esa faqat hayot davomiyligi kafolatini tushuntiruvchi ochiq sharh bilan ishlatish tavsiya etiladi. Bu refaktoringda kutilmagan crash xavfini kamaytiradi.
Kleyenslar (closures) — parent-child munosabatlaridan keyin unowned-ning ikkinchi eng keng tarqalgan ssenariysi. Capture list [unowned self] self ning kleyensdan uzoqroq yashashi kafolatlanganida qo‘llaniladi. To‘g‘ri va noto‘g‘ri ssenariylarni ko‘rib chiqaylik.
Sinxron kleyenslar — sorted, filter, map. Ular darhol joriy thread-da bajariladi, self albatta tirik. Unowned bilan capture list bu erda maqbul va tozaroq kod beradi.
class DataProcessor {
var items: [Int] = [3, 1, 4, 1, 5]
func processSorted() {
// unowned self — sorted sinxron bajariladi, self albatta tirik
let sorted = items.sorted { [unowned self] a, b in
return self.customCompare(a, b)
}
}
func customCompare(_ a: Int, _ b: Int) -> Bool { return a < b }
}
Asinxron kleyenslar — kechikish, tarmoq so‘rovlari, animatsiyalar bilan. Self kleyensni joylashtirish va uning bajarilishi o‘rtasida ozod qilinishi mumkin. Bu erda unowned self → crash. [weak self] dan foydalaning.
class NetworkLoader {
func loadData() {
// XAVFLI: asinxron kleyensda unowned self
URLSession.shared.dataTask(with: url) { [unowned self] data, _, _ in
self.handleResponse(data) // CRASH self ozod qilingan bo'lsa
}.resume()
}
func handleResponse(_ data: Data?) { }
// TO'G'RI: weak self + guard
func loadDataSafe() {
URLSession.shared.dataTask(with: url) { [weak self] data, _, _ in
guard let self else { return }
self.handleResponse(data)
}.resume()
}
}
Qoidani esda saqlang: unowned self — faqat darhol bajariladigan sinxron kleyenslar uchun. Asinxron uchun — har doim weak self + guard let. Istisno: obyektga referansni kleyens tugaguniga qadar ochiq saqlasangiz (masalan, kuchli tutashuvni boshqa o‘zgaruvchida saqlash orqali).
Unowned — kuchli, ammo xavfli vosita. Unowned crash-ga olib kelishi mumkin bo‘lgan real ssenariylar va xavfni minimallashtirish usullarini ko‘rib chiqaylik.
Asosiy xavf unowned — hayot davomiyligi kafolati bajarilishini to‘xtatadigan biznes mantig‘ining o‘zgarishi. Dasturchi kodni refaktor qiladi: mulkni o‘zgartiradi, kechiktirilgan ozod qilishni joriy qiladi, keshlashni qo‘shadi — va unowned referans kechiktirilgan bombaga aylanadi. Kompilyator ogohlantirmaydi — faqat foydalanuvchi qurilmasida crash.
Tavsiya: unowned faqat hayot davomiyligi kafolati aniq va hujjatlashtirilganida ishlating. Har bir unowned-ga sharh qo‘shing: nima uchun bu referans xavfsiz va qanday sharoitlarda buzilishi mumkin.
UIKit — unowned uchun yuqori xavf zonasi. ViewController navigatsiya (pop, dismiss), xotiradan tushirish, orientatsiya o‘zgarishi paytida istalgan vaqtda ozod qilinishi mumkin. ViewController-ni unowned self bilan kleyensga uzatsangiz — fondan qaytishda yoki animatsiya tugashida self nil bo‘lishi mumkin.
Unowned-dan foydalanishda xavfni kamaytirish uchun ushbu qoidalarga rioya qiling:
// Misol: ochiq asoslash bilan hujjatlashtirilgan unowned referans
class InvoiceLineItem {
let productName: String
let price: Decimal
// unowned Invoice — InvoiceLineItem Invoicesiz mavjud bo'la olmaydi.
// Invoice Item yaratadi va o'z o'chirilishida uni o'chiradi.
// Kafolat: Invoice kamida Item qadar yashaydi.
unowned let invoice: Invoice
init(productName: String, price: Decimal, invoice: Invoice) {
self.productName = productName
self.price = price
self.invoice = invoice
}
}
// Bu kuchli kafolat: Invoice deinitda barcha Itemlarni o'chiradi.
// kafolatning buzilishi = tuzatilishi kerak bo'lgan biznes mantiq xatosi.
Kafolatlarni hujjatlashtirish — professional standart. Katta loyihalarda (Airbnb, Uber) code review har bir unowned uchun asoslash talab qiladi. Agar kafolat aniq bo‘lmasa — weak ishlating. Unowned-ga sharh kelajak dasturchilarga nima uchun bu erda weak emasligini va qanday sharoitlar kafolatni buzishi mumkinligini tushunishga yordam beradi.
Tez-tez so‘raladigan savollar
Runtime crash EXC_BAD_ACCESS bilan. Swift kirishda unowned referansning haqiqiyligini tekshirmaydi — bu shunchaki “xom” ko‘rsatkichdir. Agar obyekt ozod qilingan bo‘lsa, xotira ustiga yozilgan va unga murojaat halokatga olib keladi. Bu tutilmaydigan istisno (try-catch emas).
Ha, agar protokol AnyObject-dan meros olsa. Unowned barcha referans turlari bilan ishlaydi: sinflar, AnyObject protokollari, Objective-C obyektlari. Qiymat turlari (struct, enum) ARC-da qatnashmaganliklari sababli unowned-ni qo‘llab-quvvatlamaydi.
Hayot davomiyligi kafolati mutlaq va aniq bo‘lganda — unowned dizayn nuqtai nazaridan xavfsizroq: unwrap talab qilmaydi, nil bo‘la olmaydi, xatolarni yashirmaydi. Agar obyekt ota-onasiz mavjud bo‘la olmasa, unowned buni ochiq kontrakt qiladi, weak esa kafolatni xiralashtiradi.
Ha: unowned tezroq, chunki nollash uchun runtime weak-jadvaliga kirishni talab qilmaydi. Ko‘pchilik ilovalarda farq sezilmaydi, lekin millionlab murojaatlar bilan yuqori yuklangan ssenariylarda unowned o‘qishda 10–20% tezroq bo‘lishi mumkin.
Refaktoring — unowned uchun asosiy xavf. Obyektning hayot davomiyligi o‘zgarishi (keshlash, asinxron operatsiyalar, qayta ishlatish) kafolatni buzishi mumkin. Kompilyator ogohlantirmaydi. Yechim: arxitektura o‘zgarishida weak-ga o‘ting yoki ogohlantirish sharhi qo‘shing.
Xulosa
unowned let yoki unowned var; non-optional va optional bo‘lishi mumkin (Swift 5.0+)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.