Sobes.tech
Middle

Na čo je typ odkazov unowned?

sobes.tech AI

Odpoveď od AI

unowned odkazy sú potrebné na riešenie cyklických odkazov (retain cycles) medzi objektmi, keď oba objekty majú silnú odkaz na seba navzájom, ale jeden z nich má kratší alebo rovnaký životný cyklus v porovnaní s druhým.

unowned sa používa, keď je známe, že odkazovaný objekt nebude nil počas celého života objektu, ktorý obsahuje odkaz. Na rozdiel od weak sa pri unowned prístupe k odkazu ne používa Optional. Ak bude objekt, na ktorý odkazuje unowned, deallocovaný skôr, než bude deallocovaný objekt s unowned odkazom, dôjde k crashi.

Príklad použitia v uzávierkach:

class Person {
    let name: String
    var apartment: Apartment?

    init(name: String) {
        self.name = name
        print("\(name) je inicializovaný")
    }

    deinit {
        print("\(name) je deinitializovaný")
    }
}

class Apartment {
    let unit: String
    // Používame `unowned`, pretože je známe, že
    // Apartment nemôže existovať bez Person
    // (v tomto kontexte). Person môže byť nil,
    // ale ak Apartment existuje, Person tiež existuje.
    unowned let tenant: Person

    init(unit: String, tenant: Person) {
        self.unit = unit
        self.tenant = tenant
        print("Apartment \(unit) je inicializovaný")
    }

    deinit {
        print("Apartment \(unit) je deinitializovaný")
    }
}

var john: Person?
var unit4A: Apartment?

john = Person(name: "John Appleseed")
// V tomto príklade môže byť tenant nil, preto `unowned`
unit4A = Apartment(unit: "4A", tenant: john!)

john!.apartment = unit4A

// Prerušíme silné odkazy, aby sme overili deallokáciu
john = nil
unit4A = nil

V tomto príklade má Person silnú odkaz na Apartment (var apartment: Apartment?). Apartment by mohol mať silnú odkaz na Person, čo by viedlo ku cyklu. Avšak, pretože v tomto kontexte Apartment logicky nemôže existovať bez Person (ktorý ho prenajíma), je odkaz z Apartment na Person označený ako unowned. Takže, keď nastavíme john = nil, Person sa deallokuje, a následne (pretože nemá žiadne silné odkazy na Apartment) sa deallokuje aj Apartment.

Hlavné rozdiely od weak:

  • Životný cyklus: unowned sa používa, keď odkazovaný objekt má rovnaký alebo dlhší životný cyklus. weak sa používa, keď odkazovaný objekt môže byť deallocovaný skôr.
  • Optional: unowned nie je Optional (okrem ak je deklarovaný ako unowned optional). weak je vždy Optional.
  • Bezpečnosť: Prístup k vlastnosti s unowned odkazom na už deallocovaný objekt spôsobí crash. Prístup k weak odkazom vráti nil.

Teda, unowned je ne-vlastnícka (non-owning) referencia, ktorá sa používa, keď je garantované, že odkazovaný objekt existuje, kým existuje objekt s unowned odkazom.