Какие объекты в Swift можно объявить как `weak` и зачем это нужно?

«Какие объекты в Swift можно объявить как `weak` и зачем это нужно?» — вопрос из категории Управление памятью, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Ключевое слово weak используется для создания неудерживающей (non-strong) ссылки на экземпляр класса. Это основной инструмент для предотвращения циклов сильных ссылок (retain cycles), которые приводят к утечкам памяти.

Принцип работы: weak-ссылка не увеличивает счетчик ссылок (retain count) объекта. Когда объект освобождается, все weak-ссылки на него автоматически становятся nil.

Типичные сценарии использования:

  • Делегаты (Delegates): Объект-делегат обычно объявляется как weak, чтобы избежать цикла, где владелец удерживает делегата, а делегат удерживает владельца.
    protocol ViewControllerDelegate: AnyObject {}
    class ViewController {
        weak var delegate: ViewControllerDelegate?
    }
  • IBOutlet в UIKit: Ссылки на элементы интерфейса, созданные в Storyboard/XIB, по умолчанию weak, так как их жизненный циклом управляет система.
  • Замыкания с [weak self]: Используется внутри замыканий, которые могут быть сохранены и вызваны позже, чтобы не создавать цикл через захваченный self.

Что НЕЛЬЗЯ объявить как weak?

  • Типы-значения (Value Types): Структуры (struct) и перечисления (enum).
  • Константы (let): Ссылка должна быть переменной (var), так как может стать nil.
  • Неопциональные типы: weak-ссылки всегда опциональны (Optional), потому что могут обнулиться.