Sobes.tech
Middle

Care este diferența dintre linkurile Wick și linkurile Anound?

sobes.tech AI

Răspuns de la AI

Referința slabă (weak) este o referință care nu crește contorul de referințe al obiectului. Este utilizată pentru prevenirea ciclurilor de referințe puternice, de exemplu, între un delegat și proprietarul său. Dacă obiectul la care indică referința slabă este deallocat, referința slabă devine automat nil.

Referința neproprietară (unowned) este, de asemenea, o referință care nu crește contorul de referințe al obiectului. Diferența față de weak este că unowned nu poate fi opțională (Optional) și trebuie să indice întotdeauna către un obiect existent. Dacă obiectul către care indică referința unowned este deallocat înainte ca referința să înceteze să existe, încercarea de a accesa această referință va duce la o eroare de execuție (eroare fatală). Este utilizată acolo unde ciclul de viață al obiectului asociat este garantat că este mai lung sau egal cu ciclul de viață al obiectului cu referința unowned (de exemplu, într-un ciclu de referințe puternice în care unul dintre obiecte are un ciclu de viață clar definit).

Comparare:

Caracteristică weak unowned
Neproprietar Da Da
Crește SC Nu Nu
Poate fi nil Da (se nulifică automat) Nu (trebuie să indice către un obiect)
Siguranță Mai sigur în cazul deallocării Mai puțin sigur (eroare fatală la accesarea unui obiect deallocat)
Tip Trebuie să fie opțional Nu poate fi opțional (implicit)
Utilizare Previne ciclurile de referințe puternice, unde obiectul poate înceta să existe mai devreme Previne ciclurile de referințe puternice, unde obiectul garantează existența sa

Exemplu de utilizare a weak pentru prevenirea ciclurilor de referințe puternice:

class Person {
    let name: String
    weak var apartment: Apartment? // referință slabă pentru a evita ciclul

    init(name: String) {
        self.name = name
        print("\(name) este inițializat")
    }

    deinit {
        print("\(name) este dezinitalizat")
    }
}

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

    init(unit: String) {
        self.unit = unit
        print("Apartament \(unit) este inițializat")
    }

    deinit {
        print("Apartament \(unit) este dezinitalizat")
    }
}

Exemplu de utilizare a unowned în contextul capturării lui self într-un închidere:

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

    lazy var asHTML: () -> String = {
        [unowned self] in // self neproprietar pentru a evita ciclul cu închiderea
        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) este dezinitalizat")
    }
}