Sobes.tech
Middle

Na co je typ odkazů unowned?

sobes.tech AI

Odpověď od AI

unowned odkazy jsou potřeba k řešení cyklických odkazů (retain cycles) mezi objekty, kdy oba objekty mají silnou odkaz na sebe navzájem, ale jeden z nich má životní cyklus kratší nebo rovnocenný s druhým.

unowned se používá, když je známo, že odkazovaný objekt nebude nil po celou dobu života objektu, který odkaz obsahuje. Na rozdíl od weak se u unowned při přístupu k odkazu nepoužívá Optional. Pokud bude objekt, na který odkazuje unowned, deallocován dříve, než bude deallocován objekt s unowned odkazem, dojde ke crashi.

Příklad použití v uzávěrkách:

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

    init(name: String) {
        self.name = name
        print("\(name) je inicializován")
    }

    deinit {
        print("\(name) je deinitializován")
    }
}

class Apartment {
    let unit: String
    // Používáme `unowned`, protože je známo, že
    // Apartment nemůže existovat bez Person
    // (v tomto kontextu). Person může být nil,
    // ale pokud Apartment existuje, Person také existuje.
    unowned let tenant: Person

    init(unit: String, tenant: Person) {
        self.unit = unit
        self.tenant = tenant
        print("Apartment \(unit) je inicializován")
    }

    deinit {
        print("Apartment \(unit) je deinitializován")
    }
}

var john: Person?
var unit4A: Apartment?

john = Person(name: "John Appleseed")
// V tomto příkladu může být tenant nil, proto `unowned`
unit4A = Apartment(unit: "4A", tenant: john!)

john!.apartment = unit4A

// Přerušíme silné odkazy, abychom ověřili deallokaci
john = nil
unit4A = nil

V tomto příkladu má Person silnou odkaz na Apartment (var apartment: Apartment?). Apartment by mohl mít silnou odkaz na Person, což by vedlo ke cyklu. Nicméně, protože v tomto kontextu Apartment logicky nemůže existovat bez Person (který ho pronajímá), je odkaz z Apartment na Person označen jako unowned. Tím, když nastavíme john = nil, je Person deallocován, a následně (protože nemá žádné silné odkazy na Apartment) je deallocován i Apartment.

Hlavní rozdíly od weak:

  • Životní cyklus: unowned se používá, když odkazovaný objekt má stejný nebo delší životní cyklus. weak se používá, když může být odkazovaný objekt dříve deallocován.
  • Optional: unowned není Optional (pokud není deklarován jako unowned optional). weak je vždy Optional.
  • Bezpečnost: Přístup k vlastnosti s unowned odkazem na již deallocovaný objekt způsobí crash. Přístup k weak odkazům vrátí nil.

Tedy, unowned je ne-vlastní (non-owning) odkaz, který se používá, když je zaručeno, že odkazovaný objekt existuje, dokud existuje objekt s unowned odkazem.