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:
unownedwird verwendet, wenn das referenzierte Objekt einen gleichen oder längeren Lebenszyklus hat.weakwird verwendet, wenn das referenzierte Objekt früher deallokiert werden kann. - Optional:
unownedist kein Optional (außer es wird alsunowned optionaldeklariert).weakist immer Optional. - Sicherheit: Der Zugriff auf eine
unowned-Eigenschaft eines bereits deallokierten Objekts führt zu einem Crash. Der Zugriff auf eineweak-Referenz gibtnilzurü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.