Вопрос проверяет понимание ARC, различий между weak и unowned и умение предотвращать краши, связанные с управлением памятью.
unowned используется для не удерживающих ссылок, которые никогда не должны быть nil. Опасность в том, что при обращении к уже деинициализированному объекту приложение упадёт с крашем. В отличие от weak, unowned не обнуляется автоматически. Поэтому его можно использовать только тогда, когда жизненный цикл объектов строго гарантирован. В реальных проектах эта гарантия часто нарушается.
unowned — мощный, но опасный инструмент, если использовать его без строгого контроля жизненного цикла объектов.
unowned от weakСначала важно зафиксировать базовое различие:
weak
не удерживает объект
автоматически становится nil
всегда опционал
unowned
не удерживает объект
никогда не становится nil
не опционал
Это различие напрямую влияет на безопасность кода.
Определение:unowned предполагает, что объект, на который ссылаются, живёт дольше или столько же, сколько и владелец ссылки.
Проблема возникает, если:
объект был освобождён
ссылка unowned всё ещё используется
происходит обращение к памяти, которой уже нет
Результат — runtime crash.
class Owner {
let child: Child
init(child: Child) {
self.child = child
child.owner = self
}
}
class Child {
unowned var owner: Owner
}
Если жизненный цикл Owner и Child нарушится (например, при рефакторинге), приложение упадёт без предупреждения.
unowned использовать допустимоunowned оправдан, когда:
жизненный цикл объектов жёстко связан
объект гарантированно существует
модель владения очевидна и стабильна
Частый пример — связи внутри одного агрегата или между объектами, создаваемыми и уничтожаемыми вместе.
Если есть хотя бы малейшее сомнение:
использовать weak
обработать nil явно
пожертвовать удобством ради стабильности
unowned опасен не сам по себе, а из-за ложного ощущения безопасности. Его стоит применять только при полной уверенности в жизненном цикле объектов, иначе он превращается в источник трудноуловимых крашей.