Sobes.tech
Middle

Swiftda qanday turdagi havolalar mavjud?

sobes.tech AI

AIdan javob

Swift'da, sinflar uchun uch asosiy turdagi referensiyalar mavjud:

  1. Kuchli Referensiya (Strong Reference):

    • Bu standart referensiya turi.
    • Kuchli referensiya ob'ektning referenslar hisobini oshiradi.
    • Ob'ekt kamida bitta kuchli referensiya mavjud bo'lsa, xotiradan chiqarilmaydi.
    • Kuchli referensiyalar tsikllari (strong reference cycles) xotira oqib ketishining asosiy sababidir.
    class Person {
        let name: String
        init(name: String) { self.name = name }
        deinit { print("\(name) deinitialization") }
    }
    
    var reference1: Person? = Person(name: "John")
    // reference1 endi kuchli referensiya, Person ob'ektining referenslar hisobini oshiradi
    
  2. Zaif Referensiya (Weak Reference):

    • weak kalit so'zi bilan e'lon qilinadi.
    • Zaif referensiya ob'ektning referenslar hisobini oshirmaydi.
    • strong reference cycles oldini olish uchun ishlatiladi.
    • Har doim opsional (Optional) bo'lib, chunki zaif referensiya ko'rsatadigan ob'ekt har qanday vaqtda deinitializatsiya qilinishi mumkin. Ob'ekt deinitializatsiya qilinsa, zaif referensiya avtomatik ravishda nil bo'ladi.
    class Apartment {
        let unit: String
        weak var tenant: Person? // Zaif referensiya
        init(unit: String) { self.unit = unit }
        deinit { print("Kvartira \(unit) deinitialization") }
    }
    
    var john: Person? = Person(name: "John")
    var unit4A: Apartment? = Apartment(unit: "4A")
    
    john?.apartment = unit4A // Agar Apartment, Person'ga kuchli referensga ega bo'lsa
    unit4A?.tenant = john   // Zaif referensiya
    
    // Kuchli referensiyalar olib tashlangandan so'ng, ob'ektlar deinitializatsiya qilinadi
    john = nil
    unit4A = nil
    // Natija: "John deinitialization", "Apartment 4A deinitialization"
    // Agar tenant kuchli referensiya bo'lsa, xotira oqib ketishi (tsikl) yuz beradi
    
  3. Nafaqatga Referensiya (Unowned Reference):

    • unowned kalit so'zi bilan e'lon qilinadi.
    • weak ga o'xshash, ob'ektning referenslar hisobini oshirmaydi.
    • strong reference cycles oldini olish uchun ishlatiladi.
    • weak dan farqli o'laroq, u opsional emas (Optional) va referans ko'rsatadigan ob'ekt, uning "hayot" davomida mavjud bo'lishi taxmin qilinadi.
    • Agar unowned referensiya ko'rsatadigan ob'ekt, undan oldin deinitializatsiya qilinsa, bajarilish vaqti xatosi (runtime error) yuz beradi.
    • Bu, har doim mavjud bo'lgan ob'ektlar uchun mos keladi, masalan, "ota- bola" holatida, ota bola egallaydi, lekin bola ota bilan kuchli bog'lanmaydi.
    class Customer {
        let name: String
        var card: CreditCard?
        init(name: String) { self.name = name }
        deinit { print("\(name) deinitialization") }
    }
    
    class CreditCard {
        let number: Int
        unowned let customer: Customer // Nafaqatga referensiya
    
        init(number: Int, customer: Customer) {
            self.number = number
            self.customer = customer // init da xavfsiz tayinlash
        }
        deinit { print("Karta #\(number) deinitialization") }
    }
    
    var john: Customer? = Customer(name: "John Doe")
    john?.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
    
    // Kuchli referensiyani olib tashlash
    john = nil
    // Natija: "John Doe deinitialization", "Karta #1234567890123456 deinitialization"
    // CreditCard'dagi nafaqatga referensiya, customer mavjud bo'lsa, amal qiladi.
    // Agar CreditCard, Customer'dan uzoqroq yashasa va customer'ga nafaqatga referensiya orqali murojaat qilinsa, xato yuz beradi.
    

weak va unowned o'rtasidagi asosiy farq:

  • weak: ob'ekt nil bo'lishi mumkin. Ob'ektlarning hayot davomiyligi qat'iy bog'lanmagan hollarda foydalaniladi (bir ob'ekt, boshqa ob'ektsiz ham mavjud bo'lishi mumkin).
  • unowned: ob'ekt, inicializatsiyadan so'ng, nil bo'lishi mumkin emas. Faqat, ob'ekt, unga murojaat qiluvchi ob'ekt mavjud bo'lsa, mavjud bo'lishi mumkin, deb ishonch bilan foydalaniladi.