Ce este numărătoarea automată a linkurilor?
sobes.tech AI
Răspuns de la AI
Numărătoarea automată a referințelor (Automatic Reference Counting, ARC) este un mecanism de gestionare a memoriei în Swift și Objective-C care urmărește și eliberează automat memoria alocată obiectelor. Fiecare instanță de clasă are un contor de referințe care crește atunci când se creează o referință puternică către obiect și scade atunci când aceasta este eliminată. Când contorul de referințe ajunge la zero, ARC de-allocatează automat obiectul și eliberează memoria ocupată.
ARC previne scurgerile de memorie și eliberările duble, simplificând gestionarea memoriei comparativ cu gestionarea manuală (cum ar fi în Objective-C fără ARC).
Există trei tipuri de referințe:
- Strong (Puternic): Crește contorul de referințe al obiectului. Este tipul de referință implicit.
- Weak (Slab): Nu crește contorul de referințe. Este folosit pentru a preveni ciclurile de referințe puternice, atunci când două obiecte se referă reciproc. Referința slabă devine
nildacă obiectul la care indică este de-allocated. Este definită cu cuvântul cheieweak. - Unowned (Fără proprietar): Nu crește contorul de referințe și are întotdeauna o valoare. Este folosit atunci când se știe că referința va indica întotdeauna către un obiect, atâta timp cât obiectul există. Spre deosebire de
weak, referința fără proprietar nu devinenilși poate cauza o eroare dacă se încearcă accesarea obiectului după de-allocare. Este definită cu cuvântul cheieunowned.
Exemplu de ciclu de referințe puternice:
class Human {
let name: String
var apartment: Apartment? // Referință puternică la un Apartment opțional
init(name: String) {
self.name = name
print("\(name) este inițializat")
}
deinit {
print("\(name) este de-initializat")
}
}
class Apartment {
let unit: String
var tenant: Human? // Referință puternică la un Human opțional
init(unit: String) {
self.unit = unit
print("Apartament \(unit) este inițializat")
}
deinit {
print("Apartament \(unit) este de-initializat")
}
}
var john: Human?
var unit4A: Apartment?
john = Human(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil
unit4A = nil
// Nu va fi afișat nici "John Appleseed este de-initializat" nici "Apartament 4A este de-initializat" din cauza ciclului de referințe puternice
Soluție pentru ciclul de referințe puternice folosind weak:
class Human {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) este inițializat")
}
deinit {
print("\(name) este de-initializat")
}
}
class Apartment {
let unit: String
weak var tenant: Human? // Referință slabă
init(unit: String) {
self.unit = unit
print("Apartament \(unit) este inițializat")
}
deinit {
print("Apartament \(unit) este de-initializat")
}
}
var john: Human?
var unit4A: Apartment?
john = Human(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil // John este de-allocated deoarece contorul său de referințe devine 0
unit4A = nil // Apartamentul este de-allocated deoarece contorul său de referințe devine 0