Ответ
Retain cycle (цикл сильных ссылок) — это ситуация утечки памяти в системах с подсчетом ссылок (ARC), когда два или более объекта удерживают друг друга через сильные (strong) ссылки, предотвращая их освобождение.
Что происходит:
- Счетчик ссылок каждого объекта никогда не достигает нуля.
- Объекты остаются в памяти навсегда (до завершения приложения).
- Вызываются
deinitэтих объектов.
Пример создания цикла:
class Person {
var bestFriend: Person? // Сильная ссылка по умолчанию
init() { print("Person инициализирован") }
deinit { print("Person деинициализирован") }
}
var alice: Person? = Person() // RefCount = 1
var bob: Person? = Person() // RefCount = 1
alice?.bestFriend = bob // RefCount bob = 2
bob?.bestFriend = alice // RefCount alice = 2
alice = nil // RefCount alice = 1 (удерживается bob.bestFriend)
bob = nil // RefCount bob = 1 (удерживается alice.bestFriend)
// Оба объекта НЕ освобождаются, deinit не печатается.
Способы разрыва цикла:
weakссылка: Используется, когда ссылаемый объект может статьnil. ARC автоматически обнуляет такую ссылку.weak var bestFriend: Person?unownedссылка: Используется, когда ссылаемый объект имеет тот же или больший срок жизни и никогда не станетnil. Не обнуляется, но приводит к крашу при обращении к освобожденному объекту.unowned let bestFriend: Person- Использование value-типов (
struct,enum): Они копируются и не создают циклических зависимостей.
Best practice: Всегда анализируйте отношения владения между объектами. Делегаты, замыкания, захватывающие self, и двунаправленные связи — типичные места для возникновения retain cycle.