Ответ
unowned — это ссылка, которая не увеличивает счетчик ссылок, но предполагается, что объект, на который она ссылается, не будет деаллоцирован в течение всего времени жизни ссылки. Обращение к unowned ссылке после деаллокации объекта вызывает краш (небезопасное разыменование).
Отличие от weak: |
weak |
unowned |
|---|---|---|
Автоматически становится nil при деаллокации объекта. |
Не становится nil. Приводит к крашу при обращении к деаллоцированному объекту. |
|
Всегда объявляется как var и имеет опциональный тип (T?). |
Может быть let и имеет неопциональный тип (T). |
|
Используется, когда ссылка может стать nil в будущем. |
Используется, когда время жизни объектов жестко связано, и ссылка никогда не переживет объект. |
Пример (классический retain cycle между Parent и Child):
class Parent {
var child: Child?
}
class Child {
// Child не может существовать без Parent, поэтому parent — unowned.
unowned let parent: Parent
init(parent: Parent) {
self.parent = parent
}
}
var parent: Parent? = Parent()
parent?.child = Child(parent: parent!)
// Нет цикла сильных ссылок: Parent -> Child (strong), Child -> Parent (unowned).
parent = nil // Все объекты корректно деаллоцируются.
// Если бы мы потом попытались обратиться к child.parent — был бы краш, но child тоже уничтожен.
Когда использовать: Для отношений, где зависимый объект (например, Child) имеет строго более короткое время жизни, чем объект-владелец (например, Parent).