Sobes.tech
Middle

Wat is het verschil tussen Wick-links en Anound-links?

sobes.tech AI

Antwoord van AI

Zwakke verwijzing (weak) is een verwijzing die de referentieteller van het object niet verhoogt. Het wordt gebruikt om sterke referentiecycli te voorkomen, bijvoorbeeld tussen een delegate en zijn eigenaar. Als het object waarnaar de zwakke verwijzing wijst wordt gedealloceerd, wordt de zwakke verwijzing automatisch nil.

Ongeowned-verwijzing (unowned) is ook een verwijzing die de referentieteller van het object niet verhoogt. Het verschil met weak is dat unowned niet optioneel kan zijn (Optional) en altijd naar een bestaand object moet wijzen. Als het object waarnaar unowned wijst wordt gedealloceerd voordat de verwijzing niet meer bestaat, zal een poging om toegang te krijgen tot die verwijzing leiden tot een runtime-fout (fatale fout). Het wordt gebruikt waar de levensduur van het gerelateerde object gegarandeerd langer of gelijk is aan die van het object met de unowned-verwijzing (bijvoorbeeld in een sterk referentiecyclus waarbij een van de objecten een duidelijk gedefinieerde levensduur heeft).

Vergelijking:

Eigenschap weak unowned
Niet-eigenend Ja Ja
Verhoogt SC Nee Nee
Kan nil zijn Ja (wordt automatisch nil) Nee (moet naar een object wijzen)
Veiligheid Veiliger bij deallocatie Minder veilig (fatale fout bij toegang tot gedealloceerd object)
Type Moet optioneel zijn Kan niet optioneel zijn (standaard)
Gebruik Voorkomen van sterke referentiecycli, waar het object eerder kan stoppen te bestaan Voorkomen van sterke referentiecycli, waar het object gegarandeerd bestaat

Voorbeeld van gebruik van weak om een sterke referentiecyclus te voorkomen:

class Person {
    let name: String
    weak var apartment: Apartment? // zwakke verwijzing om cyclus te voorkomen

    init(name: String) {
        self.name = name
        print("\(name) wordt geïnitialiseerd")
    }

    deinit {
        print("\(name) wordt gedeinitialiseerd")
    }
}

class Apartment {
    let unit: String
    var occupant: Person?

    init(unit: String) {
        self.unit = unit
        print("Appartement \(unit) wordt geïnitialiseerd")
    }

    deinit {
        print("Appartement \(unit) wordt gedeinitialiseerd")
    }
}

Voorbeeld van gebruik van unowned in de context van het vastleggen van self in een closure:

class HTMLElement {
    let name: String
    let text: String?

    lazy var asHTML: () -> String = {
        [unowned self] in // unowned self om een cyclus te voorkomen
        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) wordt gedeinitialiseerd")
    }
}