Sobes.tech
Middle

Koje vrste referenci postoje u Swift-u?

sobes.tech АИ

Одговор од АИ

Postoje tri osnovne vrste referenci u Swift-u:

  1. Strong Reference (Jake referenca):

    • Povećava brojač referenci na instancu objekta.
    • Sprečava oslobađanje objekta dok postoji bar jedna jaka referenca na njega.
    • To je podrazumevani tip reference u Swift-u.
    • Može dovesti do cikličnih referenci.
  2. Weak Reference (Slaba referenca):

    • Ne povećava brojač referenci.
    • Dozvoljava oslobađanje objekta ako na njega više nema jakih referenci.
    • Deklariše se ključnom reči weak.
    • Uvek je opcionalna (Optional), jer referencirani objekat može biti nil.
    • Koristi se za sprečavanje cikličnih referenci.
    class Person {
        let name: String
        weak var apartment: Apartment? // Slaba referenca
        init(name: String) {
            self.name = name
        }
        deinit { print("\(name) je oslobođen") }
    }
    
    class Apartment {
        let unit: String
        var tenant: Person? // Obična jaka referenca
        init(unit: String) {
            self.unit = unit
        }
        deinit { print("Stan \(unit) je oslobođen") }
    }
    
    var john: Person?
    var unit4A: Apartment?
    
    john = Person(name: "John Appleseed")
    unit4A = Apartment(unit: "4A")
    
    john!.apartment = unit4A
    unit4A!.tenant = john // Ovde bi nastala ciklična referenca bez `weak`
    
    // Referencije se nuliraju, objekti se oslobađaju
    john = nil
    unit4A = nil
    
  3. Unowned Reference (Nepodržana referenca):

    • Ne povećava brojač referenci.
    • Dozvoljava oslobađanje objekta ako na njega više nema jakih referenci.
    • Deklariše se ključnom reči unowned.
    • Nije opcionalna. Pretpostavlja se da će referencirani objekat uvek postojati dok postoji objekat koji ga sadrži.
    • Pristupanje oslobođenom objektu putem unowned izazvaće grešku u izvršenju (crash).
    • Koristi se za sprečavanje cikličnih referenci kada jedan objekat uvek mora postojati dok postoji drugi, i nije moguće da jedan od njih postane nil.
    class Customer {
        let name: String
        var card: CreditCard?
        init(name: String) {
            self.name = name
        }
        deinit { print("\(name) je oslobođen") }
    }
    
    class CreditCard {
        let number: UInt64
        unowned let customer: Customer // Nepodržana referenca
        init(number: UInt64, customer: Customer) {
            self.number = number
            self.customer = customer
        }
        deinit { print("Kreditna kartica #\(number) je oslobođena") }
    }
    
    var john: Customer? = Customer(name: "John Appleseed")
    john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
    
    // Ako obrišemo klijenta, kartica koja na njega referencira putem `unowned` će postati nevažeća, ali neće izazvati ciklus.
    john = nil // Oba objekta se oslobađaju
    

Izbor između weak i unowned zavisi od karaktera odnosa između objekata: koristite weak kada jedan objekat može da postoji bez drugog (Person bez Apartment), i unowned kada jedan objekat uvek mora da postoji dok postoji drugi (CreditCard uvek pripada Customer).