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")
}
}