Приведи пример использования unowned в Swift

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

Ответ

unowned — это модификатор захвата ссылки, который не увеличивает счетчик сильных ссылок (Retain Count), но предполагает, что захваченный объект будет существовать на протяжении всего времени жизни захватившей его сущности (например, замыкания или другого объекта). В отличие от weak, unowned ссылка не является опциональной. Попытка доступа к unowned ссылке после освобождения объекта приводит к крашу приложения (dangling pointer).

Типичный use-case: Циклическая связь, где время жизни одного объекта гарантированно короче или равно времени жизни другого.

Пример:

class Customer {
    let name: String
    var card: CreditCard? // У Customer МОЖЕТ быть карта
    init(name: String) { self.name = name }
}

class CreditCard {
    let number: String
    unowned let customer: Customer // У карты ВСЕГДА есть владелец
    init(number: String, customer: Customer) {
        self.number = number
        self.customer = customer
    }
}

// Использование
var john: Customer? = Customer(name: "John Appleseed")
john!.card = CreditCard(number: "1234-5678", customer: john!)
// CreditCard ссылается на Customer через unowned.
john = nil // Customer освобождается, CreditCard также освобождается.
// Цикл не создан, утечки нет.

Ключевые отличия от weak:

  • weak — опциональная ссылка (weak var), автоматически становится nil при освобождении объекта.
  • unowned — неопциональная ссылка, доступ к ней после освобождения объекта — неопределенное поведение (краш).

Когда использовать unowned: Когда вы уверены, что захваченный объект переживет захватывающую сущность (например, дочерний объект, который не может существовать без родительского).