Sobes.tech
Middle

Milyen típusú hivatkozások léteznek Swiftben?

sobes.tech MI

Válasz az MI-től

A Swiftben három fő hivatkozástípus létezik:

  1. Erős Hivatkozás (Strong Reference):

    • Növeli az objektum hivatkozásszámlálóját.
    • Megakadályozza az objektum felszabadulását, amíg legalább egy erős hivatkozás létezik rá.
    • A Swift alapértelmezett hivatkozástípusa.
    • Körkörös hivatkozásokat okozhat.
  2. Gyenge Hivatkozás (Weak Reference):

    • Nem növeli a hivatkozásszámlálót.
    • Engedi az objektum felszabadulását, ha nincs rá erős hivatkozás.
    • A weak kulcsszóval van deklarálva.
    • Mindig opcionális (Optional), mivel a hivatkozott objektum nil lehet.
    • Körkörös hivatkozások elkerülésére használják.
    class Person {
        let name: String
        weak var apartment: Apartment? // Gyenge hivatkozás
        init(name: String) {
            self.name = name
        }
        deinit { print("\(name) felszabadult") }
    }
    
    class Apartment {
        let unit: String
        var tenant: Person? // Szokásos erős hivatkozás
        init(unit: String) {
            self.unit = unit
        }
        deinit { print("Lakás \(unit) felszabadult") }
    }
    
    var john: Person?
    var unit4A: Apartment?
    
    john = Person(name: "John Appleseed")
    unit4A = Apartment(unit: "4A")
    
    john!.apartment = unit4A
    unit4A!.tenant = john // Itt körkörös hivatkozás alakulhatna ki, ha nem lenne `weak`
    
    // A hivatkozások nullázódnak, az objektumok felszabadulnak
    john = nil
    unit4A = nil
    
  3. Unowned Hivatkozás:

    • Nem növeli a hivatkozásszámlálót.
    • Engedi az objektum felszabadulását, ha nincs rá erős hivatkozás.
    • A unowned kulcsszóval van deklarálva.
    • Nem opcionális. Feltételezi, hogy a hivatkozott objektum mindig létezik, amíg a tartalmazó példány létezik.
    • A nem létező objektumra való hivatkozás futásidejű hibát (crash) okoz.
    • Körkörös hivatkozások elkerülésére használják, amikor az egyik példánynak mindig kell léteznie, amíg a másik is, és nem lehet nil.
    class Customer {
        let name: String
        var card: CreditCard?
        init(name: String) {
            self.name = name
        }
        deinit { print("\(name) felszabadult") }
    }
    
    class CreditCard {
        let number: UInt64
        unowned let customer: Customer // Nem tulajdonolt hivatkozás
        init(number: UInt64, customer: Customer) {
            self.number = number
            self.customer = customer
        }
        deinit { print("Kártya #\(number) felszabadult") }
    }
    
    var john: Customer? = Customer(name: "John Appleseed")
    john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
    
    // Ha a kliens törlésre kerül, a hozzá tartozó kártya is felszabadul, nem lesz körkörös hivatkozás
    john = nil // Mindkét objektum felszabadul
    

A weak és unowned közötti választás az objektumok közötti kapcsolat jellegétől függ: használja a weak-et, ha az egyik objektum többé-kevésbé létezhet függetlenül a másiktól (Person és Apartment), és az unowned-ot, ha az egyik objektumnak mindig léteznie kell, amíg a másik is (CreditCard és Customer).