Sobes.tech
Middle

Welke soorten verwijzingen zijn er in Swift?

sobes.tech AI

Antwoord van AI

In Swift zijn er drie hoofdtypen referenties:

  1. **Strong Reference (Sterke Referentie):

    • Verhoogt de referentieteller van het object.
    • Voorkomt dat het object wordt gedealloceerd zolang er ten minste één sterke referentie bestaat.
    • Dit is het standaardtype referentie in Swift.
    • De belangrijkste oorzaak van sterke referentiecirkels.
  2. **Weak Reference (Zwakke Referentie):

    • Verhoogt de referentieteller niet.
    • Staat deallocatie van het object toe als er geen sterke referenties meer zijn.
    • Wordt gedeclareerd met het sleutelwoord weak.
    • Is altijd optioneel (Optional), omdat het referentie-object nil kan worden.
    • Wordt gebruikt om cycli van sterke referenties te voorkomen, wanneer een instantie onafhankelijk van een andere kan bestaan.
    class Person {
        let name: String
        weak var apartment: Apartment? // Zwakke referentie
        init(name: String) {
            self.name = name
        }
        deinit { print("\(name) gedealloceerd") }
    }
    
    class Apartment {
        let unit: String
        var tenant: Person? // Normale sterke referentie
        init(unit: String) {
            self.unit = unit
        }
        deinit { print("Appartement \(unit) gedealloceerd") }
    }
    
    var john: Person?
    var unit4A: Apartment?
    
    john = Person(name: "John Appleseed")
    unit4A = Apartment(unit: "4A")
    
    john!.apartment = unit4A
    unit4A!.tenant = john // Hier zou een cyclus van sterke referenties ontstaan zonder weak
    
    // Referenties worden gereset, objecten worden gedealloceerd
    john = nil
    unit4A = nil
    
  3. **Unowned Reference (Onbezette Referentie):

    • Verhoogt de referentieteller niet.
    • Staat deallocatie van het object toe als er geen sterke referenties meer zijn.
    • Wordt gedeclareerd met het sleutelwoord unowned.
    • Is niet optioneel. Er wordt aangenomen dat het referentie-object altijd zal bestaan zolang de instantie die de onbezette referentie bevat, bestaat.
    • Het gebruik van een onbezette referentie op een al gedealloceerd object zal leiden tot een runtime-fout (crash).
    • Wordt gebruikt om cycli van sterke referenties te voorkomen, wanneer één instantie altijd moet bestaan zolang een andere bestaat, en het niet mogelijk is dat een van hen nil wordt, onafhankelijk van de ander (bijvoorbeeld, in self-closures).
    class Customer {
        let name: String
        var card: CreditCard?
        init(name: String) {
            self.name = name
        }
        deinit { print("\(name) gedealloceerd") }
    }
    
    class CreditCard {
        let number: UInt64
        unowned let customer: Customer // Onbezette referentie
        init(number: UInt64, customer: Customer) {
            self.number = number
            self.customer = customer
        }
        deinit { print("Kaart #\(number) gedealloceerd") }
    }
    
    var john: Customer? = Customer(name: "John Appleseed")
    john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
    
    // Als de klant wordt geannuleerd, wordt de kaart die ernaar verwijst met unowned,
    // ongeldig, maar veroorzaakt geen cyclus.
    john = nil // Beide objecten worden gedealloceerd
    

De keuze tussen weak en unowned hangt af van de aard van de relatie tussen de objecten: gebruik weak wanneer één object kan bestaan zonder het andere (Person zonder Apartment), en unowned wanneer één object altijd moet bestaan zolang het andere bestaat (CreditCard behoort altijd tot Customer).