Intern
Ce este un colector de gunoi (garbage collector)?
sobes.tech AI
Răspuns de la AI
În iOS, nu există un colector de gunoi tradițional. În schimb, se utilizează mecanismul de Referință Automată (ARC).
- Mecanism automat: ARC numără automat referințele puternice către obiecte.
- Eliberarea memoriei: Când numărul de referințe puternice către un obiect ajunge la zero, ARC eliberează memoria alocată.
- Prevenirea scurgerilor de memorie: Utilizarea corectă a referințelor puternice, slabe și neposesate (unowned) permite prevenirea scurgerilor de memorie și a ciclurilor de referințe.
Tipuri de referințe în ARC:
- Puternic (strong): Crește contorul de referințe. Este implicit.
- Slab (weak): Nu crește contorul de referințe. Devine automat
nilla deallocarea obiectului. Se folosește pentru prevenirea ciclurilor de referințe puternice. Este declarat ca un tip opțional. - Neposesat (unowned): Nu crește contorul de referințe. Se garantează că obiectul la care face referire există pe durata întregului ciclu de viață al referinței neposesate. Nu este opțional. Se folosește atunci când două obiecte au o relație puternică reciprocă, dar unul dintre ele are un ciclu de viață mai scurt.
Avantajele ARC:
- Previzibilitate: Eliberarea memoriei are loc în mod determinist, imediat ce obiectul nu mai este utilizat.
- Performanță: Nu există costuri suplimentare pentru colectorul de gunoi din fundal, care poate cauza pauze.
- Simplitate: Dezvoltatorul nu trebuie să gestioneze manual memoria în majoritatea cazurilor, dar trebuie să înțeleagă principiile de numărare a referințelor pentru a preveni scurgerile.
Exemplu de ciclu de referințe puternice:
class Person {
let name: String
var apartment: Apartment? // referință puternică la Apartment
init(name: String) { self.name = name }
deinit { print("\(name) este fiind deinitializat") }
}
class Apartment {
let unit: String
weak var tenant: Person? // referință slabă la Person pentru prevenirea ciclului
init(unit: String) { self.unit = unit }
deinit { print("Apartament \(unit) este fiind deinitializat") }
}
var john: Person?
var unit4A: Apartment?
john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john // Utilizarea weak aici este critică
john = nil
unit4A = nil
// Fără tenant weak: Atât john, cât și unit4A nu vor fi deinitializate.
// Cu tenant weak: Atât john, cât și unit4A sunt deinitializate corect.