Оба модификатора используются для разрыва сильных ссылочных циклов (retain cycles), но делают это по-разному.
?
или !
)class Person {
weak var apartment: Apartment?
// ...
}
class Customer {
unowned let creditCard: CreditCard
// ...
}
Критерий | weak | unowned |
---|---|---|
Опциональность | Да (Optional) | Нет |
Безопасность | Высокая (nil-safe) | Низкая (может крашнуться) |
Производительность | Медленнее | Быстрее |
Использование | var | let/var |
Когда использовать | Когда объект может стать nil | Когда объект гарантированно существует |
protocol DataLoaderDelegate: AnyObject {
func didLoad(data: Data)
}
class DataLoader {
weak var delegate: DataLoaderDelegate?
}
class Parent {
var child: Child?
}
class Child {
unowned let parent: Parent
init(parent: Parent) { self.parent = parent }
}
dataLoader.loadData { [weak self] data in
guard let self = self else { return }
self.handle(data)
}
// Или для гарантированно существующего self:
dataLoader.loadData { [unowned self] data in
self.handle(data) // Рискованно!
}
Использование unowned когда объект может стать nil
// Опасный код!
unowned var delegate: DataLoaderDelegate?
Циклы в замыканиях без weak/unowned
class MyClass {
var closure: (() -> Void)?
func setup() {
closure = { self.doSomething() } // Retain cycle!
}
}
Чрезмерное использование unowned "для производительности"
[weak self]
с guard: AnyObject
Правильное использование этих модификаторов предотвращает утечки памяти и делает код стабильнее.