Sobes.tech
Middle

Swiftте кайсы түрдөгү шилтемелер бар?

sobes.tech AI

AIден жооп

Swiftте үч негизги түрү бар:

  1. Күчтүү шилтеме (Strong Reference):

    • Бул шилтеме түрү боюнча алдын ала белгиленген.
    • Күчтүү шилтеме объекттин шилтемелер санын көбөйтөт.
    • Объект бошотулбайт, эгер ага кеминде бир күчтүү шилтеме болсо.
    • Эң негизги себеп — циклдик күчтүү шилтемелер (strong reference cycles).
    class Person {
        let name: String
        init(name: String) { self.name = name }
        deinit { print("\(name) is being deinitialized") }
    }
    
    var reference1: Person? = Person(name: "John")
    // reference1 азыр күчтүү шилтеме, `Person` үчүн шилтемелер саны өсөт
    
  2. Слабая шилтеме (Weak Reference):

    • weak сөзү менен белгиленет.
    • Бул шилтеме объекттин шилтемелер санын көбөйтпөйт.
    • strong reference cycles алдын алуу үчүн колдонулат.
    • Ар дайым опционал (Optional) болот, анткени шилтемелеген объект кез келген учурда деинициализация болушу мүмкүн. Деинициализация болсо, шилтеме автоматтык түрдө nil болот.
    class Apartment {
        let unit: String
        weak var tenant: Person? // Слабая шилтеме
        init(unit: String) { self.unit = unit }
        deinit { print("Apartment \(unit) is being deinitialized") }
    }
    
    var john: Person? = Person(name: "John")
    var unit4A: Apartment? = Apartment(unit: "4A")
    
    john?.apartment = unit4A // Эгер `Apartment` күчтүү шилтемеге ээ болсо `Person`ке
    unit4A?.tenant = john   // Слабая шилтеме
    
    // Күчтүү шилтемелер өчүрүлгөндөн кийин, объекттер деинициализацияланат
    john = nil
    unit4A = nil
    // Чыгуу: "John is being deinitialized", "Apartment 4A is being deinitialized"
    // Эгер `tenant` күчтүү шилтеме болсо, эс тутумдун агып кетиши болот (strong cycle)
    
  3. Unowned шилтеме (Unowned Reference):

    • unowned сөзү менен белгиленет.
    • Бул да weak сыяктуу, объекттин шилтемелер санын көбөйтпөйт.
    • strong reference cycles алдын алуу үчүн колдонулат.
    • weak сыяктуу эмес, опционал эмес (Optional) жана шилтемелеген объекттин өмүрү бүтө электе, ал дагы бар деп эсептелет.
    • Эгер unowned шилтеме көрсөтүп жаткан объект алдын ала жок болуп калса, ишке ашуу учурунда ката чыгат (runtime error).
    • Бул ысымдуу объект башка объектке караганда дайыма бар болсо, колдонулат (мисалы, "ата-эне-эркек" мамилеси, анда ата-эне баласына ээлик кылат, бирок тескерисинче эмес).
    class Customer {
        let name: String
        var card: CreditCard?
        init(name: String) { self.name = name }
        deinit { print("\(name) is being deinitialized") }
    }
    
    class CreditCard {
        let number: Int
        unowned let customer: Customer // Атайын шилтеме
    
        init(number: Int, customer: Customer) {
            self.number = number
            self.customer = customer // init ичинде коопсуз
        }
        deinit { print("Card #\(number) is being deinitialized") }
    }
    
    var john: Customer? = Customer(name: "John Doe")
    john?.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
    
    // Күчтүү шилтемени өчүрүү
    john = nil
    // Чыгуу: "John Doe is being deinitialized", "Card #1234567890123456 is being deinitialized"
    // `CreditCard`теги `customer` шилтеме иштөөдө, доке `customer` бар болсо, ал иштейт.
    // Эгер `CreditCard` узак жашаса, `Customer`ден узак жашаса жана биз `customer`ка шилтеме аркылуу кайрылсак, ката болот.
    

weak жана unowned ортосунда негизги айырма:

  • weak: объект nil болушу мүмкүн. Объекттердин өмүрү катуу байланышта эмес болсо колдонулат.
  • unowned: объект nil болбойт, ылдыйкы ылдамдыкта, ал объект бар деп ишенсе болот.