Назад к вопросам
Junior
114
questionbank

Как работает сборщик мусора (garbage collector)?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

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

ARC автоматически управляет памятью, подсчитывая количество сильных ссылок на каждый экземпляр класса (и замыкания с захватом). Когда счетчик сильных ссылок обнуляется, система освобождает память, занимаемую объектом.

Основные моменты 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) is being initialized") }
    deinit { print("\(name) is being deinitialized") }
}

class Apartment {  
    let unit: String
    unowned var tenant: Person // Бесхозная ссылка
    init(unit: String, tenant: Person) { self.unit = unit; self.tenant = tenant; print("Apartment \(unit) is being initialized") }
    deinit { print("Apartment \(unit) is being deinitialized") }
}