Middle
Jaké typy odkazů existují ve Swiftu?
sobes.tech AI
Odpověď od AI
V Swiftu existují tři hlavní typy odkazů:
-
Silný odkaz (Strong Reference):
- Zvyšuje čítač odkazů na instanci objektu.
- Zabraňuje uvolnění objektu, dokud existuje alespoň jeden silný odkaz na něj.
- Je výchozím typem odkazu ve Swiftu.
- Může způsobit cyklické odkazy.
-
Slabý odkaz (Weak Reference):
- Nezvyšuje čítač odkazů.
- Umožňuje uvolnění objektu, pokud na něj již nejsou žádné silné odkazy.
- Je deklarován klíčovým slovem
weak. - Vždy je volitelný (
Optional), protože odkazovaný objekt může býtnil. - Používá se k prevenci cyklických odkazů.
class Person { let name: String weak var apartment: Apartment? // Slabý odkaz init(name: String) { self.name = name } deinit { print("\(name) byl uvolněn") } } class Apartment { let unit: String var tenant: Person? // Obvyklý silný odkaz init(unit: String) { self.unit = unit } deinit { print("Byt \(unit) byl uvolněn") } } var john: Person? var unit4A: Apartment? john = Person(name: "John Appleseed") unit4A = Apartment(unit: "4A") john!.apartment = unit4A unit4A!.tenant = john // Tady by vznikl cyklický odkaz bez `weak` // Odkazy jsou nulovány, objekty jsou uvolněny john = nil unit4A = nil -
Unowned odkaz (Nepodílený odkaz):
- Nezvyšuje čítač odkazů.
- Umožňuje uvolnění objektu, pokud na něj již nejsou žádné silné odkazy.
- Je deklarován klíčovým slovem
unowned. - Není volitelný. Předpokládá se, že odkazovaný objekt bude vždy existovat, dokud existuje obsahující instance.
- Přístup k uvolněnému objektu přes
unownedzpůsobí runtime chybu (crash). - Používá se k prevenci cyklických odkazů, když jeden objekt musí vždy existovat, dokud existuje druhý, a není možné, aby jeden z nich byl
nil(například vázáníselfv uzávěrech).
class Customer { let name: String var card: CreditCard? init(name: String) { self.name = name } deinit { print("\(name) byl uvolněn") } } class CreditCard { let number: UInt64 unowned let customer: Customer // Nepodílený odkaz init(number: UInt64, customer: Customer) { self.number = number self.customer = customer } deinit { print("Kreditní karta #\(number) byla uvolněna") } } var john: Customer? = Customer(name: "John Appleseed") john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!) // Pokud klient zmizí, karta na něj odkazující přes `unowned` se stane neplatnou, ale nevytvoří cyklus. john = nil // Obě objekty jsou uvolněny
Volba mezi weak a unowned závisí na povaze vztahu mezi objekty: použijte weak, když jeden objekt může existovat bez druhého (Person bez Apartment), a unowned, když jeden objekt vždy musí existovat, dokud existuje druhý (CreditCard vždy patří Customer).