Ответ
unowned-ссылка — это некритичная (non-owning) ссылка, которая не увеличивает счетчик ссылок ARC. Она предполагает, что объект, на который ссылаются, будет существовать на протяжении всей жизни ссылки. В отличие от weak, unowned-ссылка всегда предполагается имеющей значение (не опциональна).
Ключевое отличие от weak: |
weak |
unowned |
|---|---|---|
Автоматически становится nil при освобождении объекта. |
Не становится nil. Обращение к освобожденной unowned-ссылке вызывает краш (небезопасная ссылка). |
|
Всегда должна быть объявлена как var и опциональный тип (weak var delegate: Delegate?). |
Может быть объявлена как let и неопциональный тип (unowned let parent: Parent). |
Когда использовать unowned:
- Когда время жизни ссылающегося объекта короче или равно времени жизни целевого объекта.
- Классический пример: иерархия «родитель-ребенок», где ребенок не может существовать без родителя.
Пример безопасного использования:
class Customer {
let id: String
var card: CreditCard? // Customer МОЖЕТ существовать без карты
init(id: String) { self.id = id }
}
class CreditCard {
let number: String
// Карта НЕ МОЖЕТ существовать без клиента. Время жизни Customer гарантированно больше.
unowned let customer: Customer
init(number: String, customer: Customer) {
self.number = number
self.customer = customer // Захват unowned-ссылки
}
}
var john: Customer? = Customer(id: "123")
john!.card = CreditCard(number: "1111-2222", customer: john!)
john = nil // Customer освобождается, затем автоматически освобождается и CreditCard.
// unowned-ссылка `customer` внутри CreditCard больше не используется.
Важно: Используйте unowned только при абсолютной уверенности в жизненном цикле. В сомнительных случаях предпочитайте weak.