Ответ
Garbage Collector (GC) — алгоритм автоматического управления памятью, который периодически находит и удаляет неиспользуемые объекты. В Swift/Objective-C для iOS/macOS GC не используется — вместо него применяется ARC (Automatic Reference Counting).
ARC vs Garbage Collector:
| Критерий | ARC (Swift/Objective-C) | Garbage Collector (Java/C#) |
|---|---|---|
| Принцип работы | Подсчёт ссылок во время компиляции/выполнения | Периодическое сканирование «живых» объектов |
| Время освобождения | Немедленно при достижении счётчиком нуля | Неопределённое (при срабатывании GC) |
| Производительность | Предсказуемая, без пауз | Возможны stop-the-world паузы |
| Циклические ссылки | Требуют weak/unowned |
Автоматически обнаруживаются |
Пример ARC в Swift:
class User {
let name: String
var friend: User? // Сильная ссылка → возможен retain cycle
init(name: String) { self.name = name }
deinit { print("(name) удалён из памяти") }
}
// Создаём циклическую ссылку
var alice: User? = User(name: "Alice")
var bob: User? = User(name: "Bob")
alice?.friend = bob // Alice → Bob
bob?.friend = alice // Bob → Alice (цикл!)
alice = nil // Память НЕ освобождается!
bob = nil // Оба объекта всё ещё в памяти
Решение с weak reference:
class User {
let name: String
weak var friend: User? // ← Слабая ссылка разрывает цикл
init(name: String) { self.name = name }
}
// Теперь при alice = nil и bob = nil память корректно освобождается
Ключевые механизмы Swift:
- Strong — обычная ссылка (увеличивает счётчик)
- Weak — не удерживает объект (автоматически становится nil)
- Unowned — как weak, но предполагает, что объект существует (краш при обращении к освобождённому)
- Autorelease pools — для Objective-C совместимости, отложенное освобождение
Ответ 18+ 🔞
А, ну вот, опять про эту вашу память, блядь. Сидишь такой, пишешь код, а тут — бац! — и вылезло. Слушай, давай по-простому, без этих ваших академических закидонов.
Вот смотри, в джаве там или шарпе — там, блядь, мусорщик. Сидит такой уборщик, ленивая жопа, и ждёт, пока куча говна не накопится. А потом раз — и stop-the-world, вся вселенная замирает, пока он метлой там машет, выгребая твои недоделанные объекты. Производительность, сука, скачет, как хуй в проруби. Паузы, неопределёнённость — пиздец, а не жизнь.
А у нас в свифте — другое дело, блядь. Тут ARC. Это не мусорщик, это, блядь, бухгалтер скрупулёзный. Каждый объект — как начальник цеха. Завёл нового работника (создал объект) — бухгалтер ставит ему единичку в графу «сильные ссылки». Передал его в другой отдел (присвоил переменной) — бухгалтер карандашиком: «плюс один». Уволился работник (переменная занулилась) — «минус один». Как только счётчик в ноль — тут же, без разговоров, вышвыривают этого работника в окно, память освобождают. Мгновенно, блядь, без пауз. Предсказуемо, как удар в ебло.
Но, как всегда, есть нюанс, ёпта. Циклические ссылки. Вот смотри, какой пиздец может случиться:
class Человек {
let имя: String
var друг: Человек? // Сильная ссылка, блядь!
init(имя: String) { self.имя = имя }
deinit { print("(имя) — откинулся, память свободна") }
}
// Создаём двух долбоёбов
var вася: Человек? = Человек(имя: "Вася")
var петя: Человек? = Человек(имя: "Петя")
// И они начинают дружить. Крепко.
вася?.друг = петя // Вася крепко держит Петю
петя?.друг = вася // Петя крепко держит Васю. Ёбушки-воробушки, замкнутый круг, блядь!
вася = nil // Думаешь, Вася свободен? Хуй там!
петя = nil // И Петя тоже! Они оба, как два мудака в обнимку, болтаются в памяти навечно!
// deinit не вызовется ни у кого! Утечка памяти, пиздец полный.
Вот видишь? Они друг за друга держатся, счётчики ссылок у них по единице, и бухгалтер (ARC) такой: «Ну раз на них ещё кто-то ссылается, пусть живут». А ссылаются-то они ДРУГ НА ДРУГА, блядь! Классический пиздец.
И что делать? А надо одного из них ослабить хватку, сделать слабаком. Для этого есть weak:
class УмныйЧеловек {
let имя: String
weak var друг: УмныйЧеловек? // ← Слабая ссылка! Не увеличивает счётчик!
init(имя: String) { self.имя = имя }
}
// Теперь, когда мы занулим переменные, они оба благополучно сдохнут, как и положено.
// Потому что Петя держит Васю слабо, не по-мужски. И как только внешняя ссылка пропала — всё, пиzдец.
Ещё есть unowned — это как weak, но для отчаянных. Предполагается, что объект, на который ссылаешься, переживёт тебя. Если ошибёшься — получишь краш, блядь, в лучших традициях. Как прыжок с крыши, рассчитывая, что внизу батут, а там асфальт.
Итог, коротко:
- Сильные (strong) — обычные, держат крепко. Основные.
- Слабые (weak) — для разрыва циклов. Автоматически становятся
nil. - Бессобственные (unowned) — для разрыва циклов, когда уверен, что объект жив. Если не уверен — летишь в тартарары, краш.
- Autorelease pools — это уже для совместимости со старым добрым Objective-C, чтоб не засирать память сразу, а чуть позже. Но это уже другая история, блядь.
Вот и вся магия. ARC — это чётко, быстро, но требует, чтобы ты, блядь, головой думал, кто на кого и как ссылается. А то получишь утечку, и приложение твоё сожрёт всю оперативку, как мартышлюшка бананы.