Middle
Was ist unowned in Swift und wie wird es verwendet?
sobes.tech KI
Antwort von AI
Unowned-Referenz (schwache indirekte Besitznahme) in Swift wird verwendet, um starke Besitzzyklus (retain cycles) zu vermeiden, wenn zwei Objekte sich gegenseitig stark referenzieren, was ihre Freigabe aus dem Speicher verhindert.
Eigenschaften von unowned:
- Garantiert, dass das Objekt, auf das sich die
unowned-Referenz bezieht, immer existiert bis zum Zeitpunkt der Nutzung dieser Referenz. - Wenn versucht wird, nach der Freigabe des verbundenen Objekts auf die
unowned-Referenz zuzugreifen, tritt ein Laufzeitfehler (runtime crash) auf. - Wird verwendet, wenn der Lebenszyklus des referenzierenden Objekts nicht länger ist als der des referenzierten Objekts. Mit anderen Worten, die
unowned-Referenz macht das Objekt nicht stark.
Beispiel für die Verwendung in einer Closure-Erfassung:
class Customer {
let name: String
var card: CreditCard?
init(name: String) {
self.name = name
}
deinit {
print("\(name) wird deinitialisiert")
}
}
class CreditCard {
let number: UInt64
unowned let customer: Customer // Unowned-Referenz auf Customer
init(number: UInt64, customer: Customer) {
self.number = number
self.customer = customer
}
deinit {
print("Karte #\(number) wird deinitialisiert")
}
}
var john: Customer? // Optionaler Customer für Freigabe
john = Customer(name: "John Appleseed")
john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
// Das Zuweisen von nil an john führt zur Freigabe von Customer und Card,
// da kein starker Besitzzyklus besteht
john = nil
Ein weiteres Beispiel - Verwendung von unowned in einer Closure-Erfassungsliste:
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = { [unowned self] in // Verwendung von unowned self
if let text = self.text {
return "<\(self.name)>\(text)</\(self.name)>"
} else {
return "<\(self.name) />"
}
}
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
deinit {
print("\(name) wird deinitialisiert")
}
}
var paragraph: HTMLElement? // Optionales HTML-Element
paragraph = HTMLElement(name: "p", text: "Hallo Welt")
print(paragraph!.asHTML())
// Das Zuweisen von nil wird HTMLElement freigeben, da die Closure es nicht stark hält
paragraph = nil
Die Wahl zwischen unowned und weak hängt davon ab, ob die Referenz nil sein kann während der Lebensdauer des Objekts. Wenn die Referenz niemals nil werden kann vor der Freigabe des Objekts, verwenden Sie unowned. Wenn sie nil werden kann, verwenden Sie weak.