Sobes.tech
Middle

Kuo skiriasi Wick nuorodos ir Anound nuorodos?

sobes.tech AI

Atsakymas iš AI

Wick nuoroda (weak) — tai nėra nuosavybinė nuoroda. Ji nepadidina objekto nuorodų skaičiaus. Ji naudojama siekiant išvengti stiprių nuorodų ciklų, pavyzdžiui, tarp delegato ir jo savininko. Jei objektas, į kurį nurodo silpna nuoroda, bus deallocuotas, silpna nuoroda automatiškai taps nil.

Unowned nuoroda (unowned) — tai taip pat nėra nuosavybinė nuoroda ir nepadidina objekto nuorodų skaičiaus. Skirtumas nuo weak tas, kad unowned negali būti pasirinktinė (Optional) ir visada turi nurodyti į esantį objektą. Jei objektas, į kurį nurodo unowned nuoroda, bus deallocuotas anksčiau, nei nuoroda nustos egzistuoti, bandymas pasiekti šią nuorodą sukels vykdymo klaidą (fatališką klaidą). Ji naudojama ten, kur susijusio objekto gyvavimo ciklas garantuotai yra ilgesnis arba lygus unowned nuorodos objekto gyvavimo ciklui (pavyzdžiui, stiprių nuorodų ciklas, kai vienas iš objektų turi aiškiai apibrėžtą gyvavimo ciklą).

Palyginimas:

Savybė weak unowned
Ne nuosavybinė Taip Taip
Padidina SC skaičių Ne Ne
Gali būti nil Taip (automatiškai nulinama) Ne (turi nurodyti į objektą)
Saugumas Daugiau saugumo, kai gali būti deallocacija Mažiau saugumo (fatališka klaida prieigos metu)
Tipas Turi būti pasirinktinė (Optional) Negali būti pasirinktinė (Optional)
Naudojimas Stiprių nuorodų ciklų prevencija, kai objektas gali anksčiau būti deallocuotas Stiprių nuorodų ciklų prevencija, kai objektas garantuotai egzistuoja

Pavyzdys, kaip naudoti weak stiprių nuorodų ciklui išvengti:

class Person {
    let name: String
    weak var apartment: Apartment? // silpna nuoroda, siekiant išvengti ciklo

    init(name: String) {
        self.name = name
        print("\(name) pradėjo veikti")
    }

    deinit {
        print("\(name) baigė veikti")
    }
}

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

    init(unit: String) {
        self.unit = unit
        print("Apartment \(unit) pradėjo veikti")
    }

    deinit {
        print("Apartment \(unit) baigė veikti")
    }
}

Pavyzdys, kaip naudoti unowned užfiksuojant self uždaryme:

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

    lazy var asHTML: () -> String = {
        [unowned self] in // unowned self, siekiant išvengti ciklo
        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) baigė veikti")
    }
}