Что такое unowned?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
unowned — это ключевое слово в Swift для объявления слабой ссылки. Используется, когда два объекта имеют сильную связь и их жизненные циклы зависят друг от друга, но мы хотим избежать циклических ссылок, которые могут помешать освобождению памяти.
Основные свойства и отличия от weak:
- Не опциональный:
unownedссылка гарантированно не будетnilна протяжении жизни объекта, на который она ссылается. - Сильная связь: Используется, когда один объект владеет другим, и они всегда существуют вместе.
- При освобождении: Если объект, на который ссылается
unownedссылка, освобождается из памяти до того, как ссылка будет использована, это приведет к крашу приложения (runtime error). Необходимо убедиться, что объект, на который ссылаетсяunownedссылка, существует дольше, чем сама ссылка. - Применение: Чаще используется для делегатов, когда делегат всегда существует дольше, чем объект, который его вызывает, или в замыканиях, чтобы избежать циклических ссылок на
self, когда замыкание не захватывает сильную ссылку наself.
Пример использования в замыкании:
// swift
class MyClass {
var name: String
var closure: (() -> Void)?
init(name: String) {
self.name = name
}
func setupClosure() {
closure = { [unowned self] in // Использование unowned self
print("My name is \(self.name)")
}
}
deinit {
print("\(name) deinitialized")
}
}
Пример использования для делегата (хотя weak чаще используется для делегатов, unowned тоже возможен, если делегат гарантированно живет дольше):
// swift
protocol MyDelegate: AnyObject { // AnyObject требует ссылочный тип
func doSomething()
}
class DataSource {
unowned var delegate: MyDelegate // unowned ссылка на делегата
init(delegate: MyDelegate) {
self.delegate = delegate
}
func performAction() {
delegate.doSomething()
}
deinit {
print("DataSource deinitialized")
}
}
class MyController: MyDelegate {
var dataSource: DataSource?
override init() {
super.init()
dataSource = DataSource(delegate: self)
}
func doSomething() {
print("Delegate method called")
}
deinit {
print("MyController deinitialized")
}
}
Выбор между weak и unowned зависит от того, является ли ссылка опциональной и гарантированно ли существует объект, на который она ссылается, до конца жизни ссылки. Если есть вероятность, что объект может быть освобожден до использования ссылки, следует использовать weak. Если гарантия существования есть, и ссылка не должна быть опциональной, можно использовать unowned.