Для чего используется unowned ссылка в Swift и чем она отличается от weak?

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

Ответ

unowned — это ссылка, которая не увеличивает счетчик ссылок, но предполагается, что объект, на который она ссылается, не будет деаллоцирован в течение всего времени жизни ссылки. Обращение к unowned ссылке после деаллокации объекта вызывает краш (небезопасное разыменование).

Отличие от weak: weak unowned
Автоматически становится nil при деаллокации объекта. Не становится nil. Приводит к крашу при обращении к деаллоцированному объекту.
Всегда объявляется как var и имеет опциональный тип (T?). Может быть let и имеет неопциональный тип (T).
Используется, когда ссылка может стать nil в будущем. Используется, когда время жизни объектов жестко связано, и ссылка никогда не переживет объект.

Пример (классический retain cycle между Parent и Child):

class Parent {
    var child: Child?
}

class Child {
    // Child не может существовать без Parent, поэтому parent — unowned.
    unowned let parent: Parent
    init(parent: Parent) {
        self.parent = parent
    }
}

var parent: Parent? = Parent()
parent?.child = Child(parent: parent!)
// Нет цикла сильных ссылок: Parent -> Child (strong), Child -> Parent (unowned).
parent = nil // Все объекты корректно деаллоцируются.
// Если бы мы потом попытались обратиться к child.parent — был бы краш, но child тоже уничтожен.

Когда использовать: Для отношений, где зависимый объект (например, Child) имеет строго более короткое время жизни, чем объект-владелец (например, Parent).