Sobes.tech
Middle

Welche Arten von Referenzen gibt es in Swift?

sobes.tech KI

Antwort von AI

In Swift gibt es drei Hauptarten von Referenzen:

  1. **Starke Referenz (Strong Reference):

    • Erhöht den Referenzzähler des Objekts.
    • Verhindert die Deallokation des Objekts, solange mindestens eine starke Referenz besteht.
    • Ist der Standardreferenztyp in Swift.
    • Die Hauptursache für Zyklen starker Referenzen.
  2. **Schwache Referenz (Weak Reference):

    • Erhöht den Referenzzähler nicht.
    • Ermöglicht die Deallokation des Objekts, wenn keine starken Referenzen mehr vorhanden sind.
    • Wird mit dem Schlüsselwort weak deklariert.
    • Ist immer optional (Optional), da das referenzierte Objekt nil werden kann.
    • Wird verwendet, um Zyklen starker Referenzen zu verhindern, wenn eine Instanz unabhängig von einer anderen existieren kann.
    class Person {
        let name: String
        weak var apartment: Apartment? // Schwache Referenz
        init(name: String) {
            self.name = name
        }
        deinit { print("\(name) deallokiert") }
    }
    
    class Apartment {
        let unit: String
        var tenant: Person? // Normale starke Referenz
        init(unit: String) {
            self.unit = unit
        }
        deinit { print("Wohnung \(unit) deallokiert") }
    }
    
    var john: Person?
    var unit4A: Apartment?
    
    john = Person(name: "John Appleseed")
    unit4A = Apartment(unit: "4A")
    
    john!.apartment = unit4A
    unit4A!.tenant = john // Hier würde ein Zyklus starker Referenzen ohne weak entstehen
    
    // Referenzen werden gelöscht, Objekte deallokiert
    john = nil
    unit4A = nil
    
  3. **Unbesessene Referenz (Unowned Reference):

    • Erhöht den Referenzzähler nicht.
    • Ermöglicht die Deallokation des Objekts, wenn keine starken Referenzen mehr vorhanden sind.
    • Wird mit dem Schlüsselwort unowned deklariert.
    • Ist nicht optional. Es wird angenommen, dass das referenzierte Objekt immer existiert, solange die Instanz, die die unbesessene Referenz enthält, existiert.
    • Die Verwendung einer unbesessenen Referenz auf ein bereits deallokiertes Objekt führt zu einem Laufzeitfehler (Crash).
    • Wird verwendet, um Zyklen starker Referenzen zu verhindern, wenn eine Instanz immer existieren muss, solange eine andere existiert, und es keine Möglichkeit gibt, dass eine von ihnen nil wird (z.B. self in Closures).
    class Customer {
        let name: String
        var card: CreditCard?
        init(name: String) {
            self.name = name
        }
        deinit { print("\(name) deallokiert") }
    }
    
    class CreditCard {
        let number: UInt64
        unowned let customer: Customer // Unbesessene Referenz
        init(number: UInt64, customer: Customer) {
            self.number = number
            self.customer = customer
        }
        deinit { print("Karte #\(number) deallokiert") }
    }
    
    var john: Customer? = Customer(name: "John Appleseed")
    john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
    
    // Wenn der Kunde gelöscht wird, wird die Karte, die sich auf ihn bezieht, mit unowned,
    // ungültig, verursacht aber keinen Zyklus.
    john = nil // Beide Objekte werden deallokiert
    

Die Wahl zwischen weak und unowned hängt von der Natur der Beziehung zwischen den Objekten ab: Verwenden Sie weak, wenn ein Objekt ohne das andere existieren kann (Person ohne Apartment), und unowned, wenn ein Objekt immer existieren muss, solange das andere existiert (CreditCard gehört immer zu Customer).