Weak Reference (kuchsiz havola) — ARC da obyektning ushlab qolish hisoblagichini oshirmaydigan havoladir. Apple Swift Language Guide, 2026 ma'lumotlariga ko'ra, weak-havolalar weak kalit so'zi bilan e'lon qilinadi va har doim ixtiyoriy turga ega. Obyekt bo'shatilganda, unga bo'lgan barcha weak-havolalar avtomatik ravishda nil ga o'rnatiladi, bu osilib qolgan ko'rsatkichlarning oldini oladi va kuchsiz havolalarni retain cycle ni uzish uchun xavfsiz mexanizmga aylantiradi.
Asosiy
weak kalit so'zi; tur har doim ixtiyoriy (?)Weak Reference — ARC (Automatic Reference Counting) dagi egalik qilmaydigan havoladir. Obyektning retain count ni oshiruvchi va uning hayotini kafolatlaydigan strong-havoladan farqli o'laroq, weak-havola obyektning hali ham havolalar mavjud bo'lsa ham bo'shatilishiga imkon beradi. Bo'shatilgandan so'ng weak-havola avtomatik ravishda nil ga o'rnatiladi — bu zeroing weak deb ataladi.
Zeroing weak — Swift va Objective-C runtime ning asosiy xususiyatidir. Obyektning havola hisoblagichi nolga yetganda va obyekt deallokatsiya qilinganda, runtime ushbu obyektga barcha weak-havolalarni (maxsus weak-jadvalda saqlanadi) aylanib chiqadi va ularni nil ga o'rnatadi. Bu weak-havolalar orqali bo'shatilgan xotiraga kirish (use-after-free) mumkin emasligini kafolatlaydi — har qanday o'qish nil qaytaradi.
Apple WWDC 2012 Session 406 ma'lumotlariga ko'ra, zeroing weak havolalar qo'lda xotira boshqaruvida (MRR) keng tarqalgan osilib qolgan ko'rsatkichlar (dangling pointers) bilan bog'liq crash xatolarning butun sinfini yo'q qildi. MRR da kuchsiz havolalar faqat __unsafe_unretained sifatida mavjud edi — ular nollanmasdi va bo'shatilgan obyektga kirish EXC_BAD_ACCESS ga olib kelardi.
Apple ekotizimining ikkala tilida weak-havolalarni e'lon qilish sintaksisini ko'rib chiqamiz. Umumiy runtime ga qaramasdan, sintaksis farqlanadi, ammo semantika bir xil.
Swift da weak-havolalar var oldidan weak kalit so'zi bilan e'lon qilinadi. Tur har doim ixtiyoriy bo'lishi kerak (Type?), chunki havola istalgan vaqtda nollanishi mumkin. Konstantalar (let) weak bo'la olmaydi — faqat o'zgaruvchilar.
class ViewController: UIViewController {
// weak-xususiyatlar: faqat var, faqat optional
weak var delegate: ViewControllerDelegate?
weak var parentView: UIView?
weak var completionHandler: ((Bool) -> Void)? // ⚠️ closure'lar weak saqlamaydi
// ⬆️ Xato: weak faqat class-turlariga qo'llanilishi mumkin, closure ga emas
}
Muhim: weak faqat sinf namunalariga (class-types), AnyObject ga va AnyObject dan meros olgan protokollarga qo'llaniladi. Struct, enum va closure weak bo'la olmaydi — ular qiymat turlaridir va ARC da ishtirok etmaydi.
Objective-C da weak-xususiyatlar __weak atributi yoki property da weak modifikatori orqali e'lon qilinadi:
// Objective-C: weak property
@interface MyViewController : UIViewController
@property (weak, nonatomic) id<MyDelegate> delegate;
@end
// Lokal weak-o'zgaruvchi
__weak MyObject *weakRef = someStrongObject;
Objective-C runtime ham zeroing weak ni ta'minlaydi, ammo qo'shimcha ravishda weak ni C-strukturalari va ba'zi Core Foundation obyektlari bilan ishlatishni bloklaydi. Ular uchun __unsafe_unretained qo'llaniladi — zeroing siz.
Kuchsiz havolalar — universal yechim emas, balki aniq stsenariylar uchun vositadir. Hamma joyda weak ishlatish haddan tashqari murakkablikka olib keladi va o'qishni yomonlashtiradi. To'g'ri qo'llash stsenariylarini ko'rib chiqamiz.
Delegate — weak uchun asosiy stsenariy. Egalik qiluvchi obyekt (masalan, UITableView) o'ziga strong-havola saqlaydi, delegate (UIViewController) esa jadvalga egalik qilmasligi kerak. Apple SDK barcha delegate va dataSource larning weak bo'lishini kafolatlaydi. O'z protokollaringiz uchun har doim weak var delegate dan foydalaning.
Farzand obyekt ota-ona ga havola qilishi kerak bo'lganda (masalan, ChildViewController koordinatorga kirish uchun), weak-havoladan foydalaning. Ota-ona farzandga egalik qiladi (strong), farzand ota-onani kuzatadi (weak) — retain cycle istisno qilingan.
Capture list [weak self] — sinfning xususiyatlari sifatida saqlanadigan closure'larda retain cycle dan qochishning standart usulidir. Agar self closure tugashidan oldin bo'shatilishi mumkin bo'lsa — weak self majburiydir.
| Stsenariy | Weak | Strong |
|---|---|---|
| Delegate | ✅ Har doim weak | ❌ Retain cycle |
| Parent → Child | ❌ Kerak emas (ota-ona egalik qilishi kerak) | ✅ Strong |
| Child → Parent | ✅ Weak | ❌ Retain cycle |
| Asinxron callback | ✅ [weak self] | ❌ Retain cycle xavfi |
| Kuchli bog'lanish (owned) | ❌ unowned | ✅ Strong |
Umumiy qoida: agar A obyekti B ga egalik qilsa (A → B strong), unda B → A weak yoki unowned bo'lishi kerak. Strong-havolalar yo'nalishi har doim egadan tobelikka qarab bo'lishi kerak.
Ham weak, ham unowned retain count ni oshirmaydi, ammo obyekt deallokatsiyasidan keyin xatti-harakatlari farqlanadi. Ularning orasida tanlov umr kafolatlari masalasidir.
Weak: avtomatik nollanadi (nil), tur har doim optional, ishlatishdan oldin unwrap talab qiladi. Xavfsiz — nil ga kirish crashga olib kelmaydi.
Unowned: nollanmaydi, tur non-optional. Agar obyekt bo'shatilgan bo'lsa, unowned-havola osilib qolgan ko'rsatkichga aylanadi — unga kirish runtime crashga olib keladi. Unowned obyekt havola qiluvchi tomondan kam yashamasligini taxmin qiladi.
Weak ni tanlang, agar: obyekt istalgan vaqtda deallokatsiya qilinishi mumkin bo'lsa (ekran yopilgandan keyin delegate), obyektning umrini boshqarmasangiz yoki kafolatlarga shubha qilsangiz. Weak — universal xavfsiz tanlov.
Unowned ni tanlang, agar: obyekt kafolatlangan holda havola qiluvchidan oldin bo'shatilmasa (masalan, Customer → CreditCard, burada karta mijozsiz mavjud emas). Unowned unwrapsiz non-optional API beradi, bu kodda qulayroq.
class Order {
let id: Int
var items: [Item] = []
init(id: Int) { self.id = id }
// Kuchli bog'lanish: Order Item ga egalik qiladi
func addItem(name: String) {
let item = Item(name: name, order: self)
items.append(item)
}
}
class Item {
let name: String
unowned let order: Order // ✅ unowned — Item Ordersiz yashamaydi
init(name: String, order: Order) {
self.name = name
self.order = order
}
}
// Weak bilan misol: umr kafolatisiz delegate
protocol NetworkServiceDelegate: AnyObject {
func didReceiveResponse(data: Data)
}
class NetworkService {
weak var delegate: NetworkServiceDelegate? // ✅ weak — delegate ketishi mumkin
}
Misolda Item unowned dan foydalanadi, chunki buyurtma elementi buyurtmaning o'zisiz mavjud bo'la olmaydi — umr kafolati temir-betondir. NetworkService weak dan foydalanadi, chunki delegate (masalan, ViewController) istalgan vaqtda yopilishi va bo'shatilishi mumkin.
Kuchsiz havolalar — kuchli vosita, ammo iOS rivojlanishida to'g'ri qo'llash uchun tushunish muhim bo'lgan cheklovlarga ega.
Kuchsiz havolalar strong dan sekinroq: har bir kirishda runtime obyektning bo'shatilganligini tekshiradi (weak-jadvalda lookup). Stsenariylarning katta ko'pchiligida farq sezilmaydi, ammo millionlab kirishlari bo'lgan issiq sikllarda weak tor bo'g'in bo'lishi mumkin. Yuqori yuklangan stsenariylar uchun strong dan foydalaning va arxitekturani qayta tashkil qiling.
Struct, enum, tuple — ARC da ishtirok etmaydigan qiymat turlaridir. Weak struct e'lon qilish urinishi kompilyatsiya xatosiga olib keladi. Qiymat turiga kuchsiz havola saqlash uchun class turida o'rash yoki closure dan foydalaning.
Zeroing weak thread-xavfsiz: agar obyekt bir tarmoqda bo'shatilsa, weak-havola barcha tarmoqlarda atomik ravishda nollanadi. Biroq weak-havolani o'qish va undan foydalanish orasidagi bo'shliq poyga holatiga olib kelishi mumkin — obyekt weak-havolani olish va undan foydalanish o'rtasida bo'shatiladi. Yechim: strong-tutib olish kuchsiz havolani lokal o'zgaruvchiga.
// Weak bilan ko'p tarmoqlilikda race condition
func performAsync() {
weak var weakSelf = self
queue.async {
// ⚠️ weakSelf tekshirish va ishlatish o'rtasida nil bo'lishi mumkin
if weakSelf != nil {
weakSelf!.doSomething() // CRASH agar nil bo'lgan bo'lsa
}
}
}
// ✅ Tuzatish: ishlatish vaqtiga kuchli tutib olish
func performAsyncSafe() {
queue.async { [weak self] in
guard let strongSelf = self else { return }
strongSelf.doSomething() // strongSelf — lokal strong-havola
}
}
Xavfsiz variantda weak self tutib olinadi, so'ngra darhol lokal strong-o'zgaruvchiga strongSelf ochiladi. Agar self hali tirik bo'lsa — blokning bajarilishi davomida tirik qoladi. Agar yo'q bo'lsa — guard ishga tushadi va kod bajarilmaydi. Ushbu idiom — Swift da asinxron closure'lar uchun standart naqshdir.
IBOutlet Interface Builder da weak bo'lishi kerak, chunki ko'rinish ierarxiyasi allaqachon subview da strong-havola saqlaydi. Kontrollerda strong-havolani takrorlash retain cycle yaratmaydi, ammo ortiqcha. Outlet ga kuchsiz havola — Apple tavsiyasi, garchi ko'plab dasturchilar kodni soddalashtirish uchun strong dan foydalansa.
Tez-tez beriladigan savollar
Yo'q, weak faqat mavjud obyektga yoki nil ga ishora qilishi mumkin. Yangi obyekt yaratishda avval strong-havola olasiz (initsializator orqali), va faqat undan keyin kuchsiz havolani tayinlashingiz mumkin. Boshida weak nil — normal holat.
Weak faqat referens turlarini (sinflar) boshqaradigan ARC ga asoslangan. Qiymat turlari (struct, enum) tayinlashda nusxalanadi va retain count ga ega emas. Qiymat turlarining kuchsiz bog'lanishi uchun closure'lar yoki weak-xususiyatli class o'rashidan foydalaning.
Weak-havolaga har bir kirish runtime-jadvalida lookup ni bajaradi. Millionlab iteratsiyali sikl ichida bu strong-havoladan 2–5 marta sekinroq bo'lishi mumkin. Issiq yo'llar uchun weak ni sikl oldidan lokal strong-o'zgaruvchiga nusxalang.
Obyektga barcha strong-havolalar yo'qolganda — skop oxirida, xususiyat qayta o'rnatilganda, ekran yopilganda. Ko'p tarmoqli muhitda bu ikki kod qatori orasida sodir bo'lishi mumkin. Har doim weak ni guard let yoki if let orqali tekshiring.
Semantik jihatdan bir xil: ikkalasi ham zeroing weak ni ta'minlaydi. Farqlari: Swift optional-tur va var talab qiladi, Objective-C property modifikatoridan foydalanadi. Objective-C shuningdek __unsafe_unretained ni qo'llab-quvvatlaydi — zeroing siz kuchsiz havola (osilib qolgan ko'rsatkich xavfi).
Xulosa
weak var + ixtiyoriy tur; faqat class-turlari va AnyObject protokollariBiz 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.