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