Sobes.tech
Middle

V čem spočívá rozdíl mezi Wick odkazy a Anound odkazy?

sobes.tech AI

Odpověď od AI

Wick-odkaz (weak) — je to ne vlastnické odkazovanie. Nezvyšuje počet odkazov na objekt. Používa sa na zabránenie cyklov silných odkazov, napríklad medzi delegátom a jeho vlastníkom. Ak je objekt, na ktorý odkazuje slabý odkaz, deallokovaný, slabý odkaz sa automaticky stáva nil.

Unowned-odkaz (unowned) — je tiež ne vlastnický odkaz a nezvyšuje počet odkazov na objekt. Rozdiel od weak je v tom, že unowned nemôže byť voliteľný (Optional) a vždy musí odkazovať na existujúci objekt. Ak je objekt, na ktorý odkazuje unowned, deallokovaný skôr, než odkaz prestane existovať, pokus o prístup k tomuto odkazu spôsobí chybu behu (fatálnu chybu). Používa sa tam, kde je životný cyklus súvisiaceho objektu garantovane dlhší alebo rovný životnému cyklu objektu s unowned-odkazom (napríklad cyklus silných odkazov, kde jeden z objektov má jasne definovaný životný cyklus).

Porovnanie:

Funkcia weak unowned
Ne vlastnické Áno Áno
Zvyšuje SC Nie Nie
Môže byť nil Áno (automaticky nulované) Nie (musí odkazovať na objekt)
Bezpečnosť Bezpečnejšie pri možnom deallokovaní Menej bezpečné (fatálna chyba pri prístupe k deallokovanému)
Typ Musí byť voliteľný Nemôže byť voliteľný (predvolené)
Použitie Prevencia cyklov silných odkazov, kde objekt môže prestať existovať skôr Prevencia cyklov silných odkazov, kde objekt je garantovane existujúci

Príklad použitia weak na prevenciu cyklu silných odkazov:

class Person {
    let name: String
    weak var apartment: Apartment? // weak odkaz na zabránenie cyklu

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

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

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

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

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

Príklad použitia unowned v kontexte zachytenia self v uzávierke:

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

    lazy var asHTML: () -> String = {
        [unowned self] in // unowned self na zabránenie retain cycle s uzávierkou
        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) je deinitializovaný")
    }
}