Почему в Swift нельзя объявить weak-константу (let)?

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

Ответ

В Swift нельзя объявить weak-ссылку как константу (let), потому что weak-ссылки должны быть изменяемыми (var).

Причина: Система ARC (Automatic Reference Counting) может в любой момент обнулить (nil) weak-ссылку, когда на объект, на который она указывает, не останется сильных ссылок. Эта операция присваивания nil является изменением значения переменной, что запрещено для констант.

Пример, вызывающий ошибку компиляции:

class MyClass {}

// Корректно: weak-ссылка должна быть var
weak var weakVariable: MyClass?

// Ошибка компиляции: 'weak' variable must be mutable
weak let weakConstant: MyClass?
//         ^^^
// Компилятор: 'weak' must be a mutable variable

Как это работает:

  1. Когда создается weak-ссылка, runtime добавляет ее в специальную таблицу.
  2. Когда объект освобождается (его счетчик сильных ссылок достигает нуля), runtime проходит по этой таблице и автоматически устанавливает все weak-ссылки на этот объект в nil.
  3. Поскольку это действие изменяет значение ссылки, она обязана быть объявлена как var.

Следствие: Все weak-ссылки по своей природе являются опциональными (Optional<T>), так как они могут стать nil в процессе выполнения программы.