Middle
Welche Arten von Verweisen gibt es in Swift?
sobes.tech KI
Antwort von AI
In Swift gibt es drei Hauptarten von Referenzen auf Klasseninstanzen:
-
Starke Referenz (Strong Reference):
- Dies ist der Standardreferenztyp.
- Eine starke Referenz erhöht den Referenzzähler des Objekts.
- Das Objekt wird nicht aus dem Speicher freigegeben, solange mindestens eine starke Referenz besteht.
- Der Hauptgrund für Speicherlecks bei zyklischen starken Referenzen (
strong reference cycles).
class Person { let name: String init(name: String) { self.name = name } deinit { print("\(name) wird deinitialisiert") } } var reference1: Person? = Person(name: "John") // reference1 ist jetzt eine starke Referenz, der Referenzzähler von Person erhöht sich -
Schwache Referenz (Weak Reference):
- Wird mit dem Schlüsselwort
weakdeklariert. - Eine schwache Referenz erhöht den Referenzzähler des Objekts nicht.
- Wird verwendet, um
strong reference cycleszu verhindern. - Ist immer optional (
Optional), da das Objekt, auf das die schwache Referenz zeigt, jederzeit deinitialisiert werden kann. Wenn das Objekt deinitialisiert wird, wird die schwache Referenz automatischnil.
class Apartment { let unit: String weak var tenant: Person? // Schwache Referenz init(unit: String) { self.unit = unit } deinit { print("Apartment \(unit) wird deinitialisiert") } } var john: Person? = Person(name: "John") var unit4A: Apartment? = Apartment(unit: "4A") john?.apartment = unit4A // Wenn Apartment eine starke Referenz auf Person hätte unit4A?.tenant = john // Schwache Referenz // Nach Entfernen der starken Referenzen werden die Objekte deinitialisiert john = nil unit4A = nil // Ausgabe: "John wird deinitialisiert", "Apartment 4A wird deinitialisiert" // Wenn tenant eine starke Referenz wäre, würde es zu einem Speicherleck kommen (zyklischer Zyklus) - Wird mit dem Schlüsselwort
-
Unbesitzte Referenz (Unowned Reference):
- Wird mit dem Schlüsselwort
unowneddeklariert. - Ähnlich wie die schwache Referenz, erhöht sie den Referenzzähler des Objekts nicht.
- Wird ebenfalls verwendet, um
strong reference cycleszu verhindern. - Im Gegensatz zu
weakist sie nicht optional (Optional) und geht davon aus, dass das referenzierte Objekt während der gesamten "Lebensdauer" der unbesitzten Referenz existiert. - Wenn das referenzierte Objekt vor der unbesitzten Referenz deinitialisiert wird, tritt ein Laufzeitfehler (
runtime error) auf. - Geeignet für Situationen, in denen ein Objekt immer existiert, solange ein anderes verbundenes Objekt existiert (z.B. "Eltern-Kind", wobei der Elternteil das Kind besitzt, aber das Kind den Elternteil nicht stark besitzt).
class Customer { let name: String var card: CreditCard? init(name: String) { self.name = name } deinit { print("\(name) wird deinitialisiert") } } class CreditCard { let number: Int unowned let customer: Customer // Unbesitzte Referenz init(number: Int, customer: Customer) { self.number = number self.customer = customer // Sichere Zuweisung im init } deinit { print("Karte #\(number) wird deinitialisiert") } } var john: Customer? = Customer(name: "John Doe") john?.card = CreditCard(number: 1234_5678_9012_3456, customer: john!) // Entfernen der starken Referenz auf Customer john = nil // Ausgabe: "John Doe wird deinitialisiert", "Karte #1234567890123456 wird deinitialisiert" // Die unbesitzte Referenz in CreditCard war gültig, solange customer existierte. // Wenn CreditCard länger lebt als Customer und wir versuchen, auf customer über die unbesitzte Referenz zuzugreifen, tritt ein Fehler auf. - Wird mit dem Schlüsselwort
Hauptunterschied zwischen weak und unowned:
weak: Das Objekt kannnilsein. Verwenden Sie es, wenn die Lebensdauer der Objekte nicht strikt verbunden ist (eines kann ohne das andere existieren).unowned: Das Objekt kann nach der Initialisierung nichtnilsein. Verwenden Sie es, wenn Sie sicher sind, dass das referenzierte Objekt mindestens so lange existiert, wie das referenzierende Objekt.