Sobes.tech
Middle

Wozu dient der unowned Referenztyp?

sobes.tech KI

Antwort von AI

Referenzen unowned sind notwendig, um zyklische Referenzen (Retain Cycles) zwischen Objekten aufzulösen, wenn beide Objekte eine starke Referenz zueinander haben, aber eines der Objekte eine kürzere oder gleiche Lebensdauer hat.

unowned wird verwendet, wenn bekannt ist, dass das referenzierte Objekt während der gesamten Lebensdauer des Objekts, das die Referenz enthält, nicht nil sein wird. Im Gegensatz zu weak wird beim Zugriff auf eine unowned-Referenz kein Optional verwendet. Wenn das auf das unowned-Objekt referenzierte Objekt vor dem Objekt mit der unowned-Referenz deallokiert wird, tritt ein Crash auf.

Beispiel für die Verwendung in Closures:

class Person {
    let name: String
    var apartment: Apartment?

    init(name: String) {
        self.name = name
        print("\(name) wird initialisiert")
    }

    deinit {
        print("\(name) wird deinitialisiert")
    }
}

class Apartment {
    let unit: String
    // Wir verwenden `unowned`, weil bekannt ist,
    // dass ein Apartment ohne eine Person nicht existieren kann
    // (in diesem Kontext). Person kann `nil` sein,
    // aber wenn das Apartment existiert, existiert auch die Person.
    unowned let tenant: Person

    init(unit: String, tenant: Person) {
        self.unit = unit
        self.tenant = tenant
        print("Apartment \(unit) wird initialisiert")
    }

    deinit {
        print("Apartment \(unit) wird deinitialisiert")
    }
}

var john: Person?
var unit4A: Apartment?

john = Person(name: "John Appleseed")
// In diesem Beispiel kann `tenant` `nil` sein, daher
// wird eine `unowned`-Optionale Referenz verwendet
unit4A = Apartment(unit: "4A", tenant: john!)

john!.apartment = unit4A

// Wir lösen die starken Referenzen auf, um die Deallokation zu testen
john = nil
unit4A = nil

In diesem Beispiel hat Person eine starke Referenz auf Apartment (var apartment: Apartment?). Apartment könnte eine starke Referenz auf Person haben, was einen Zyklus erzeugen würde. Da in diesem Kontext Apartment jedoch nicht ohne Person existieren kann (die es mietet), wird die Referenz von Apartment auf Person unowned. Somit wird beim Setzen von john = nil Person deallokiert, und infolgedessen (da keine starken Referenzen auf Apartment bestehen) auch Apartment.

Hauptunterschiede zu weak:

  • Lebenszyklus: unowned wird verwendet, wenn das referenzierte Objekt einen gleichen oder längeren Lebenszyklus hat. weak wird verwendet, wenn das referenzierte Objekt früher deallokiert werden kann.
  • Optional: unowned ist kein Optional (außer es wird als unowned optional deklariert). weak ist immer Optional.
  • Sicherheit: Der Zugriff auf eine unowned-Eigenschaft eines bereits deallokierten Objekts führt zu einem Crash. Der Zugriff auf eine weak-Referenz gibt nil zurück.

Daher ist unowned eine nicht-eigentümliche (non-owning) Referenz, die verwendet wird, wenn die Existenz des referenzierten Objekts garantiert ist, solange das Objekt mit der unowned-Referenz existiert.