Вопрос проверяет умение находить утечки памяти и понимать, почему объекты не освобождаются.
Retain cycle возникает, когда два или более объекта удерживают друг друга сильными ссылками. В результате retain count никогда не становится равным нулю. Такие объекты не освобождаются, и возникает утечка памяти. Чаще всего retain cycle появляются в замыканиях, делегатах и взаимных ссылках между объектами.
Retain cycle — одна из самых частых и опасных причин утечек памяти в iOS-приложениях.
Retain cycle — ситуация, при которой группа объектов образует цикл сильных ссылок и не может быть освобождена ARC.
Типовая схема:
A сильно ссылается на B
B сильно ссылается на A
Оба объекта:
имеют retain count ≥ 1
никогда не доходят до нуля
Замыкания:
захватывают self по умолчанию сильно
часто хранятся дольше, чем ожидается
Пример логики (упрощённо):
class Example {
var callback: (() -> Void)?
func setup() {
callback = {
// self используется здесь
self.doSomething()
}
}
}
Здесь:
self удерживает callback
callback удерживает self
Делегаты без weak
Таймеры (Timer)
NotificationCenter
Long-living сервисы и синглтоны
deinitЕсли deinit не вызывается:
почти наверняка есть утечка
Инструмент Xcode позволяет:
увидеть цепочки ссылок
найти цикл
понять, кто кого удерживает
Leaks
Allocations
Используются для поиска долгоживущих объектов.
использовать [weak self] или [unowned self]
делать делегаты weak
явно разрывать связи при завершении работы
Retain cycle возникают из-за логических циклов сильных ссылок. Их нельзя “починить” ARC — только правильной архитектурой и внимательной работой с ссылками.