Weak Reference — bu nima, sintaksisi va mobil rivojlanishda qo'llash

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

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 Reference — obyektning retain count ga ta'sir qilmaydigan havola; obyekt bo'shatilganda nollanadi
  • E'lon qilish — var oldidan weak kalit so'zi; tur har doim ixtiyoriy (?)
  • Qo'llash — delegate'lar, closure'lar, parent-child munosabatlari retain cycle ni uzish uchun
  • Xavfsizlik — obyekt deallokatsiyasidan keyin avtomatik nil ga o'rnatish (zeroing weak)
  • Unowned dan farqi — weak nollanadi va xavfsiz, unowned nollanmaydi va umr kafolatini talab qiladi

Weak Reference nima?

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.

Swift va Objective-C da weak sintaksisi

Apple ekotizimining ikkala tilida weak-havolalarni e'lon qilish sintaksisini ko'rib chiqamiz. Umumiy runtime ga qaramasdan, sintaksis farqlanadi, ammo semantika bir xil.

Swift

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.

swift
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

Objective-C da weak-xususiyatlar __weak atributi yoki property da weak modifikatori orqali e'lon qilinadi:

objective-c
// 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 havolalarni qachon qo'llash kerak

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'lar (Delegate pattern)

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.

Parent-Child qayta aloqa bilan

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.

Asinxron closure'lar

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.

StsenariyWeakStrong
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.

Weak vs Unowned: taqqoslash va stsenariylar

Ham weak, ham unowned retain count ni oshirmaydi, ammo obyekt deallokatsiyasidan keyin xatti-harakatlari farqlanadi. Ularning orasida tanlov umr kafolatlari masalasidir.

Farqlar

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.

Qachon weak tanlash kerak

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.

Qachon unowned tanlash kerak

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.

swift
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 havolalarning cheklovlari va tuzoqlar

Kuchsiz havolalar — kuchli vosita, ammo iOS rivojlanishida to'g'ri qo'llash uchun tushunish muhim bo'lgan cheklovlarga ega.

Weak samaradorligi

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.

Weak qiymat turlariga qo'llanilmaydi

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.

Weak ko'p tarmoqlilikda

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.

swift
// 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.

UIView va weak outlet

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

Weak-havola hali yaratilmagan obyektga ishora qila oladimi?

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.

Nima uchun weak faqat class-turlari bilan ishlaydi?

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 sikl ichida samaradorlikka qanday ta'sir qiladi?

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.

Weak-havola qachon kutilmaganda nil bo'lishi mumkin?

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.

Weak Objective-C dagi __weak dan qanday farq qiladi?

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 Reference — egalik qilmaydigan, retain count ni oshirmaydigan va deallokatsiyada avtomatik nollanadigan havola
  • Sintaksisweak var + ixtiyoriy tur; faqat class-turlari va AnyObject protokollari
  • Zeroing weak — runtime bo'shatilgan obyektga barcha weak-havolalarni nollaydi, osilib qolgan ko'rsatkichlarning oldini oladi
  • Stsenariylar — delegate'lar, parent-child qayta aloqa bilan, asinxron closure'lar ([weak self])
  • Weak vs Unowned — weak nollanadi (xavfsiz), unowned nollanmaydi (crash xavfi, ammo non-optional)
  • Samaradorlik — weak runtime-jadvalida lookup sababli strong dan sekinroq; issiq yo'llar uchun strong ga nusxalang
  • Tavsiya — umr kafolatlariga ishonchingiz komil bo'lmasa — weak ni tanlang

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