Какво е unowned?
sobes.tech AI
Отговор от 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.