Sobes.tech
Junior

Как работи събирачът на боклук (garbage collector)?

sobes.tech AI

Отговор от AI

В контекста на разработката за iOS/macOS, Swift/Objective-C не използва събирач на отпадъци (GC), а автоматично броене на препратки (Automatic Reference Counting, ARC).

ARC автоматично управлява паметта, като брои броя на силните препратки (Strong) към всяка инстанция на клас (и затваряния с каптур). Когато броячът на силните препратки достигне нула, системата освобождава паметта, заета от обекта.

Основни точки за ARC:

  • Силни препратки (Strong): Увеличават брояча на препратките. Обектът остава в паметта, докато има поне една силна препратка.
  • Слаби препратки (Weak): Не увеличават брояча. Използват се за предотвратяване на цикли на силни препратки. Посочват към опционален обект и стават nil, когато обектът бъде освободен.
  • Несвойствени препратки (Unowned): Не увеличават брояча. Използват се, когато е известен жизненият цикъл на обектите и един обект винаги ще съществува, докато съществува друг. Препратката не е опционална. Ако обектът, към който се отнася unowned, бъде освободен, опитът за достъп до него ще доведе до грешка по време на изпълнение.

ARC работи по време на компилацията, като вмъква извиквания към retain (увеличаване на брояча) и release (намаляване на брояча) в съответния код.

class MyClass {  
    var prop: String = ""  
}

var reference1: MyClass? = MyClass() // Брояч = 1
var reference2 = reference1 // Брояч = 2

reference1 = nil // Брояч = 1
reference2 = nil // Брояч = 0, обектът се освобождава
class Person {  
    let name: String
    weak var apartment: Apartment? // Слаба препратка за избягване на цикъл
    init(name: String) { self.name = name; print("\(name) се инициализира") }
    deinit { print("\(name) се деинициализира") }
}

class Apartment {  
    let unit: String
    unowned var tenant: Person // Несвойствена препратка
    init(unit: String, tenant: Person) { self.unit = unit; self.tenant = tenant; print("Апартамент \(unit) се инициализира") }
    deinit { print("Апартамент \(unit) се деинициализира") }
}