Mi az az unowned?
sobes.tech MI
Válasz az MI-től
Az unowned a Swift kulcsszava a gyenge (weak) hivatkozás deklarálására. Akkor használjuk, amikor két objektum erős kapcsolatban áll, és életciklusuk egymástól függ, de el akarjuk kerülni a ciklikus hivatkozásokat, amelyek megakadályozhatják a memória felszabadítását.
Fő jellemzők és különbségek a weak-hez képest:
- Nem opcionális: Az
unownedhivatkozás nem lesznilaz objektum életciklusa során, amelyre hivatkozik. - Erős kapcsolat: Akkor használjuk, amikor egy objektum másikat birtokol, és mindkettő mindig együtt létezik.
- Felszabadításkor: Ha az objektum, amelyre az
unownedhivatkozás utal, a memória felszabadítása előtt kerül felszabadításra, ez futási hibát (runtime error) eredményez. Biztosnak kell lennünk abban, hogy a hivatkozott objektum hosszabb ideig létezik, mint maga a hivatkozás. - Alkalmazás: Gyakran használják delegáltakhoz, amikor a delegált mindig hosszabb ideig létezik, mint a hívó objektum, vagy closures-ben, hogy elkerüljék a ciklikus hivatkozásokat
self-re, amikor a closure nem erős hivatkozást foglal magábaself-re.
Példa használatra closure-ben:
// swift
class MyClass {
var name: String
var closure: (() -> Void)?
init(name: String) {
self.name = name
}
func setupClosure() {
closure = { [unowned self] in // unowned self használata
print("Az én nevem \(self.name)")
}
}
deinit {
print("\(name) felszabadult")
}
}
Delegált példában (bár a weak gyakrabban használatos delegáltaknál, az unowned szintén lehetőség, ha a delegált garantáltan hosszabb ideig él):
// swift
protocol MyDelegate: AnyObject { // Az `AnyObject` referencia típus szükséges
func doSomething()
}
class DataSource {
unowned var delegate: MyDelegate // unowned referencia a delegáltra
init(delegate: MyDelegate) {
self.delegate = delegate
}
func performAction() {
delegate.doSomething()
}
deinit {
print("DataSource felszabadult")
}
}
class MyController: MyDelegate {
var dataSource: DataSource?
override init() {
super.init()
dataSource = DataSource(delegate: self)
}
func doSomething() {
print("Delegált metódus hívva")
}
deinit {
print("MyController felszabadult")
}
}
A weak és unowned közötti választás attól függ, hogy a referencia opcionális-e, és az objektum, amelyre hivatkozik, garantáltan létezik-e a referencia életének végéig. Ha fennáll annak a lehetősége, hogy az objektum a referencia használata előtt felszabadul, akkor a weak-et kell használni. Ha a létezés garantált, és a referencia nem lehet opcionális, akkor az unowned használható.