Sobes.tech
Middle

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")
    }
}