Ответ
unowned — это модификатор ссылки в Swift, который, как и weak, не увеличивает счетчик сильных ссылок (retain count), но с критическим отличием: он предполагает, что объект назначения никогда не станет nil в течение времени жизни ссылки. Если объект освобождается, обращение к unowned-ссылке вызывает краш приложения (dangling pointer).
Ключевые отличия от weak:
weakссылки всегда optional (weak var delegate: Delegate?) и автоматически обнуляются (nil).unownedссылки non-optional (unowned let parent: Parent) и не обнуляются.
Когда использовать unowned:
- Когда время жизни объекта и ссылки совпадает или объект живет дольше.
- Для устранения циклов сильных ссылок в отношениях, где один объект логически "владеет" другим (например, родитель-ребенок).
Пример безопасного использования:
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: "12345")
john!.card = CreditCard(number: "1111-2222", customer: john!)
john = nil // Теперь и Customer, и CreditCard освобождены. Обращение к card.customer вызовет краш.
Правило: Используйте unowned только при абсолютной уверенности, что объект не будет освобожден раньше ссылки. В сомнительных случаях предпочитайте weak.
Ответ 18+ 🔞
А, ну это же про unowned, да? Вот эта штука, которая как weak, только с хуёвым характером и без страховки.
Смотри, представь: weak — это как твой друг, который может в любой момент слинять, и ты это знаешь. Поэтому ты к нему обращаешься осторожно, через вопросики (weak var friend: Friend?). А если он свалил, то у тебя в руках просто nil, и приложение не падает, ты просто пожимаешь плечами — «ну, бывает».
А вот unowned — это как твой родной отец, который, по твоей наивной уверенности, никогда в жизни не умрёт. Ты на него ссылаешься напрямую, без всяких вопросиков (unowned let dad: Dad). И всё вроде ок, пока он жив. Но если он таки, прости господи, откинулся — и ты попробуешь к нему обратиться... Пиздец. Краш. Приложение в тапки. Dangling pointer, ёпта. Указатель в никуда, в пустоту, в освобождённую память. В рот меня чих-пых!
Так когда же эту опасную хуйню использовать?
Только в одном случае: когда ты на 146% уверен, что объект, на который ссылаешься, живёт столько же или дольше, чем твой текущий объект. Это как отношения «родитель-ребёнок». Ребёнок (карта) не может существовать без родителя (клиента). Родитель создаёт ребёнка и передаёт ему ссылку на себя. Пока жив родитель — жив и ребёнок. Значит, можно смело юзать unowned.
Вот, смотри на этот код, тут всё чётко:
class Customer {
let id: String
var card: CreditCard? // У клиента МОЖЕТ быть карта
init(id: String) { self.id = id }
}
class CreditCard {
let number: String
// Карта НЕ МОЖЕТ существовать без клиента. Клиент живет дольше или столько же.
// Поэтому смело — unowned. Без знаков вопроса.
unowned let customer: Customer
init(number: String, customer: Customer) {
self.number = number
self.customer = customer // Карта рождается, уже зная своего создателя.
}
}
// Живёт себе Джон-клиент
var john: Customer? = Customer(id: "12345")
// Он заводит карту и говорит ей: «Я твой отец, вот ссылка на меня, храни её, но сильно не держись (unowned)».
john!.card = CreditCard(number: "1111-2222", customer: john!)
// А теперь представь, что Джон взял и умер (nil).
john = nil
// Всё. И клиент, и его карта освобождаются. Цикла нет, молодцы.
// Но если бы где-то завалялась ещё одна сильная ссылка на карту, и она попробовала бы обратиться к card.customer... Э, сабака сука! Краш! Потому что customer уже в лучшем из миров.
Главное правило, блядь: Если у тебя в голове промелькнула хоть тень сомнения — «а вдруг объект освободится раньше?» — выкинь unowned нахуй и бери weak. Лучше optional, чем краш. Волнение ебать, терпения ноль ебать, когда приложение падает из-за такой ерунды.
А то ведь бывает, мартышлюшка, понаставит unowned везде, где попало, а потом удивление пиздец — «ой, а чё это оно крешится?». Сам от себя охуел.