V čem spočívá rozdíl mezi Wick odkazy a Anound odkazy?
sobes.tech AI
Odpověď od AI
Wick-odkaz (weak) — je to ne vlastnické odkazovanie. Nezvyšuje počet odkazov na objekt. Používa sa na zabránenie cyklov silných odkazov, napríklad medzi delegátom a jeho vlastníkom. Ak je objekt, na ktorý odkazuje slabý odkaz, deallokovaný, slabý odkaz sa automaticky stáva nil.
Unowned-odkaz (unowned) — je tiež ne vlastnický odkaz a nezvyšuje počet odkazov na objekt. Rozdiel od weak je v tom, že unowned nemôže byť voliteľný (Optional) a vždy musí odkazovať na existujúci objekt. Ak je objekt, na ktorý odkazuje unowned, deallokovaný skôr, než odkaz prestane existovať, pokus o prístup k tomuto odkazu spôsobí chybu behu (fatálnu chybu). Používa sa tam, kde je životný cyklus súvisiaceho objektu garantovane dlhší alebo rovný životnému cyklu objektu s unowned-odkazom (napríklad cyklus silných odkazov, kde jeden z objektov má jasne definovaný životný cyklus).
Porovnanie:
| Funkcia | weak |
unowned |
|---|---|---|
| Ne vlastnické | Áno | Áno |
| Zvyšuje SC | Nie | Nie |
Môže byť nil |
Áno (automaticky nulované) | Nie (musí odkazovať na objekt) |
| Bezpečnosť | Bezpečnejšie pri možnom deallokovaní | Menej bezpečné (fatálna chyba pri prístupe k deallokovanému) |
| Typ | Musí byť voliteľný | Nemôže byť voliteľný (predvolené) |
| Použitie | Prevencia cyklov silných odkazov, kde objekt môže prestať existovať skôr | Prevencia cyklov silných odkazov, kde objekt je garantovane existujúci |
Príklad použitia weak na prevenciu cyklu silných odkazov:
class Person {
let name: String
weak var apartment: Apartment? // weak odkaz na zabránenie cyklu
init(name: String) {
self.name = name
print("\(name) je inicializovaný")
}
deinit {
print("\(name) je deinitializovaný")
}
}
class Apartment {
let unit: String
var occupant: Person?
init(unit: String) {
self.unit = unit
print("Apartment \(unit) je inicializovaný")
}
deinit {
print("Apartment \(unit) je deinitializovaný")
}
}
Príklad použitia unowned v kontexte zachytenia self v uzávierke:
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = {
[unowned self] in // unowned self na zabránenie retain cycle s uzávierkou
if let text = self.text {
return "<\(self.name)>\(text)</\(self.name)>"
} else {
return "<\(self.name) />"
}
}
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
deinit {
print("\(name) je deinitializovaný")
}
}