Sobes.tech
Junior

Cum funcționează colectorul de gunoi (garbage collector)?

sobes.tech AI

Răspuns de la AI

În contextul dezvoltării iOS/macOS, Swift/Objective-C nu utilizează colectorul de gunoi (GC), ci numărătoarea automată a referințelor (Automatic Reference Counting, ARC).

ARC gestionează automat memoria numărând numărul de referințe puternice (Strong) către fiecare instanță de clasă (și închideri cu captură). Când contorul de referințe puternice ajunge la zero, sistemul eliberează memoria ocupată de obiect.

Puncte cheie ale ARC:

  • Referințe puternice (Strong): Crește contorul de referințe. Obiectul rămâne în memorie atâta timp cât are cel puțin o referință puternică.
  • Referințe slabe (Weak): Nu cresc contorul de referințe. Sunt folosite pentru a evita ciclurile de referințe puternice. Se referă opțional la un obiect și devin nil când obiectul este eliberat.
  • Referințe neposesedate (Unowned): Nu cresc contorul de referințe. Sunt folosite când ciclul de viață al obiectelor este cunoscut și un obiect va exista întotdeauna atâta timp cât altul. Referința nu este opțională. Dacă obiectul la care se face referire unowned este eliberat, accesul la el va duce la o eroare în timpul execuției.

ARC funcționează în timpul compilării, inserând apeluri la retain (creștere contor) și release (scădere contor) în codul corespunzător.

class MyClass {  
    var prop: String = ""  
}

var reference1: MyClass? = MyClass() // Contor = 1
var reference2 = reference1 // Contor = 2

reference1 = nil // Contor = 1
reference2 = nil // Contor = 0, obiectul este eliberat
class Person {  
    let name: String
    weak var apartment: Apartment? // Referință slabă pentru a evita cicluri
    init(name: String) { self.name = name; print("\(name) este inițializat") }
    deinit { print("\(name) este deinitializat") }
}

class Apartment {  
    let unit: String
    unowned var tenant: Person // Referință neposesedată
    init(unit: String, tenant: Person) { self.unit = unit; self.tenant = tenant; print("Apartament \(unit) este inițializat") }
    deinit { print("Apartament \(unit) este deinitializat") }
}