Чем unowned ссылка отличается от weak и когда ее используют?

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

Ответ

unowned — это модификатор ссылки, который, как и weak, не увеличивает retain count объекта, но предполагает, что объект будет существовать на протяжении всей жизни ссылающегося на него объекта.

Ключевые отличия от weak: Аспект unowned weak
Опциональность Неопциональная (всегда предполагается развернутой). Всегда опциональная (T?).
Поведение при деаллокации Обращение к деаллоцированной unowned-ссылке вызывает краш (небезопасное разыменование). Автоматически становится nil.
Синтаксис unowned let parent: Parent weak var delegate: Delegate?

Когда использовать unowned:

  1. При гарантированном времени жизни, когда ссылаемый объект имеет равный или больший жизненный цикл.
  2. Для избежания циклов сильных ссылок в отношениях типа "родитель-ребенок".

Классический пример:

class Customer {
    let id: String
    var card: CreditCard? // Дочерний объект
    init(id: String) { self.id = id }
}

class CreditCard {
    let number: String
    unowned let customer: Customer // Карта не может существовать без Клиента
    init(number: String, customer: Customer) {
        self.number = number
        self.customer = customer
    }
}

var john: Customer? = Customer(id: "123")
john!.card = CreditCard(number: "1111-2222", customer: john!)
john = nil // Customer и CreditCard деаллоцируются вместе, нет цикла.

Правило выбора: Используйте unowned, если абсолютно уверены, что объект "хозяин" переживет объект "зависимый". В сомнительных случаях всегда выбирайте безопасный weak.