Middle
Ce este unowned în limbajul Swift și cum se folosește?
sobes.tech AI
Răspuns de la AI
Referința ne deținută (gestionare indirectă slabă) în Swift este utilizată pentru a evita ciclurile de retenție puternice (retain cycles), atunci când două obiecte se referă reciproc în mod puternic, împiedicând eliberarea lor din memorie.
Caracteristici ale unowned:
- Asigură că obiectul la care se face referire prin referința
unownedexiste întotdeauna până în momentul utilizării acestei referințe. - Dacă se încearcă accesarea referinței
unowneddupă ce obiectul asociat a fost eliberat, va avea loc o eroare la timpul de execuție (runtime crash). - Se folosește atunci când ciclul de viață al obiectului care face referire nu este mai lung decât cel al obiectului la care se face referire. Cu alte cuvinte, referința cu
unownednu face ca obiectul să devină puternic.
Exemplu de utilizare în captarea unei închideri:
class Customer {
let name: String
var card: CreditCard?
init(name: String) {
self.name = name
}
deinit {
print("\(name) este eliminat")
}
}
class CreditCard {
let number: UInt64
unowned let customer: Customer // Referință ne deținută la Customer
init(number: UInt64, customer: Customer) {
self.number = number
self.customer = customer
}
deinit {
print("Card #\(number) este eliminat")
}
}
var john: Customer? // Customer opțional pentru eliberare
john = Customer(name: "John Appleseed")
john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
// Atribuirea lui nil la john va duce la eliberarea lui Customer și Card,
// deoarece nu există un ciclu de retenție puternic
john = nil
Alt exemplu - utilizarea unowned în lista de captare a unei închideri:
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = { [unowned self] in // Utilizare de unowned self
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 eliminat")
}
}
var paragraph: HTMLElement? // Element HTML opțional
paragraph = HTMLElement(name: "p", text: "salut lume")
print(paragraph!.asHTML())
// Atribuirea lui nil va elibera HTMLElement, deoarece închidere nu îl menține puternic
paragraph = nil
Alegerea între unowned și weak depinde de dacă referința poate fi nil în timpul vieții obiectului. Dacă referința nu poate deveni niciodată nil înainte de eliberarea obiectului, folosiți unowned. Dacă poate, folosiți weak.