Ce este unowned?
sobes.tech AI
Răspuns de la AI
unowned — este un cuvânt cheie în Swift pentru declararea unei referințe slabe. Este utilizat atunci când două obiecte au o relație puternică și ciclurile lor de viață depind unul de celălalt, dar dorim să evităm referințele ciclice care pot împiedica eliberarea memoriei.
Proprietăți principale și diferențe față de weak:
- Non-opțional: Referința
unownednu va finilpe durata vieții obiectului la care face referire. - Relație puternică: Se folosește atunci când un obiect deține altul și ambele există întotdeauna împreună.
- La eliberare: Dacă obiectul la care face referire referința
unownedeste eliberat din memorie înainte ca referința să fie utilizată, acest lucru va duce la o eroare de rulare (runtime error). Este necesar să ne asigurăm că obiectul referențiat există mai mult timp decât referința însăși. - Aplicare: Se folosește mai ales pentru delegați, atunci când delegatul există întotdeauna mai mult timp decât obiectul care îl apelează, sau în closures pentru a evita referințele ciclice la
self, atunci când closure-ul nu capturează o referință puternică laself.
Exemplu de utilizare într-un closure:
// swift
class MyClass {
var name: String
var closure: (() -> Void)?
init(name: String) {
self.name = name
}
func setupClosure() {
closure = { [unowned self] in // Utilizare de unowned self
print("Numele meu este \(self.name)")
}
}
deinit {
print("\(name) a fost dezalocat")
}
}
Exemplu de utilizare pentru un delegat (deși weak este mai frecvent utilizat pentru delegați, unowned este, de asemenea, posibil dacă delegatul garantează că va trăi mai mult):
// swift
protocol MyDelegate: AnyObject { // AnyObject necesită un tip de referință
func doSomething()
}
class DataSource {
unowned var delegate: MyDelegate // referință `unowned` către delegat
init(delegate: MyDelegate) {
self.delegate = delegate
}
func performAction() {
delegate.doSomething()
}
deinit {
print("DataSource a fost dezalocat")
}
}
class MyController: MyDelegate {
var dataSource: DataSource?
override init() {
super.init()
dataSource = DataSource(delegate: self)
}
func doSomething() {
print("Metoda delegatului a fost apelată")
}
deinit {
print("MyController a fost dezalocat")
}
}
Alegerea între weak și unowned depinde de faptul dacă referința este opțională și dacă obiectul referențiat există garantat până la sfârșitul vieții referinței. Dacă există posibilitatea ca obiectul să fie eliberat înainte de utilizarea referinței, trebuie folosit weak. Dacă garanția existenței este asigurată și referința nu trebuie să fie opțională, se poate folosi unowned.