Middle
Ce tipuri de referințe există în Swift?
sobes.tech AI
Răspuns de la AI
În Swift, există trei tipuri principale de referințe:
-
**Referință Puternică (Strong Reference):
- Crește contorul de referințe al obiectului.
- Previene deallocarea obiectului atât timp cât există cel puțin o referință puternică.
- Este tipul implicit de referință în Swift.
- Cauza principală a ciclurilor de referințe puternice.
-
**Referință Slabă (Weak Reference):
- Nu crește contorul de referințe.
- Permite deallocarea obiectului dacă nu mai există referințe puternice.
- Se declară folosind cuvântul cheie
weak. - Este întotdeauna opțională (
Optional), deoarece obiectul referențiat poate deveninil. - Se folosește pentru a preveni ciclurile de referințe puternice, atunci când o instanță poate exista independent de alta.
class Person { let name: String weak var apartment: Apartment? // Referință slabă init(name: String) { self.name = name } deinit { print("\(name) deallocat") } } class Apartment { let unit: String var tenant: Person? // Referință puternică normală init(unit: String) { self.unit = unit } deinit { print("Apartament \(unit) deallocat") } } var john: Person? var unit4A: Apartment? john = Person(name: "John Appleseed") unit4A = Apartment(unit: "4A") john!.apartment = unit4A unit4A!.tenant = john // Aici s-ar putea crea un ciclu de referințe puternice fără weak // Referințele sunt resetate, obiectele sunt deallocat john = nil unit4A = nil -
**Referință Neasumată (Unowned Reference):
- Nu crește contorul de referințe.
- Permite deallocarea obiectului dacă nu mai există referințe puternice.
- Se declară folosind cuvântul cheie
unowned. - Nu este opțională. Se presupune că obiectul referențiat va exista întotdeauna atâta timp cât instanța care conține referința neasumată există.
- Utilizarea unei referințe neasumate pe un obiect deja deallocat va duce la o eroare de execuție (crash).
- Se folosește pentru a preveni ciclurile de referințe puternice, atunci când o instanță trebuie să existe întotdeauna atâta timp cât alta există, și nu există posibilitatea ca unul dintre ele să devină
nilindependent de celălalt (de exemplu, în închiderileself).
class Customer { let name: String var card: CreditCard? init(name: String) { self.name = name } deinit { print("\(name) deallocat") } } class CreditCard { let number: UInt64 unowned let customer: Customer // Referință neasumată init(number: UInt64, customer: Customer) { self.number = number self.customer = customer } deinit { print("Card #\(number) deallocat") } } var john: Customer? = Customer(name: "John Appleseed") john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!) // Dacă clientul este anulat, cardul care face referire la el cu unowned, // va deveni invalid, dar nu va cauza ciclu. john = nil // Ambele obiecte sunt deallocat
Alegerea între weak și unowned depinde de natura relației dintre obiecte: folosiți weak când un obiect poate exista fără celălalt (Person fără Apartment), și unowned când un obiect trebuie să existe întotdeauna atâta timp cât celălalt există (CreditCard aparține întotdeauna Customer).