Was ist der Unterschied zwischen Wick-Links und Anound-Links?
sobes.tech KI
Antwort von AI
Der schwache Verweis (weak) ist ein Verweis, der den Referenzzähler des Objekts nicht erhöht. Er wird verwendet, um starke Referenzzyklen zu verhindern, zum Beispiel zwischen einem Delegierten und seinem Besitzer. Wenn das Objekt, auf das der schwache Verweis zeigt, deallokiert wird, wird der schwache Verweis automatisch nil.
Der unbesitzende Verweis (unowned) ist ebenfalls ein Verweis, der den Referenzzähler des Objekts nicht erhöht. Der Unterschied zu weak besteht darin, dass unowned nicht optional sein kann (Optional) und immer auf ein existierendes Objekt zeigen muss. Wenn das Objekt, auf das unowned zeigt, deallokiert wird, bevor der Verweis nicht mehr existiert, führt der Zugriff auf diesen Verweis zu einem Laufzeitfehler (fataler Fehler). Es wird dort verwendet, wo der Lebenszyklus des verbundenen Objekts garantiert länger oder gleich lang ist wie der des Objekts mit dem unowned-Verweis (zum Beispiel in einem starken Referenzzyklus, bei dem eines der Objekte einen klar definierten Lebenszyklus hat).
Vergleich:
| Eigenschaft | weak |
unowned |
|---|---|---|
| Nicht besitzend | Ja | Ja |
| Erhöht SC | Nein | Nein |
Kann nil sein |
Ja (wird automatisch nullifiziert) | Nein (muss auf ein Objekt zeigen) |
| Sicherheit | Sicherer bei möglicher Deallokation | Weniger sicher (fataler Fehler bei Zugriff auf deallokiertes Objekt) |
| Typ | Muss optional sein | Kann nicht optional sein (Standard) |
| Verwendung | Verhindert starke Referenzzyklen, bei denen das Objekt vorzeitig aufhört zu existieren | Verhindert starke Referenzzyklen, bei denen das Objekt garantiert existiert |
Beispiel für die Verwendung von weak, um einen starken Referenzzyklus zu verhindern:
class Person {
let name: String
weak var apartment: Apartment? // schwacher Verweis, um Zyklus zu vermeiden
init(name: String) {
self.name = name
print("\(name) wird initialisiert")
}
deinit {
print("\(name) wird deinitialisiert")
}
}
class Apartment {
let unit: String
var occupant: Person?
init(unit: String) {
self.unit = unit
print("Apartment \(unit) wird initialisiert")
}
deinit {
print("Apartment \(unit) wird deinitialisiert")
}
}
Beispiel für die Verwendung von unowned im Kontext des Captures von self in einer Closure:
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = {
[unowned self] in // unowned self, um einen Zyklus mit der Closure zu vermeiden
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")
}
}