Middle
Aké typy odkazov existujú v Swift?
sobes.tech AI
Odpoveď od AI
V Swift existujú tri hlavné typy odkazov na inštancie tried:
-
Silná referencia (Strong Reference):
- Ide o predvolený typ odkazu.
- Silná referencia zvyšuje počítadlo odkazov objektu.
- Objekt nebude uvoľnený z pamäti, kým na neho existuje aspoň jedna silná referencia.
- Hlavnou príčinou únikov pamäti sú cyklické silné odkazy (
strong reference cycles).
class Person { let name: String init(name: String) { self.name = name } deinit { print("\(name) is being deinitialized") } } var reference1: Person? = Person(name: "John") // reference1 je teraz silná referencia, počet odkazov na Person sa zvyšuje -
Slabá referencia (Weak Reference):
- Deklaruje sa pomocou kľúčového slova
weak. - Slabá referencia nezvyšuje počítadlo odkazov na objekt.
- Používa sa na prevenciu
strong reference cycles. - Vždy je voliteľná (
Optional), pretože objekt, na ktorý odkazuje slabá referencia, môže byť de-inicializovaný kedykoľvek. Pri de-inicializácii sa slabá referencia automaticky stávanil.
class Apartment { let unit: String weak var tenant: Person? // Slabá referencia init(unit: String) { self.unit = unit } deinit { print("Apartment \(unit) is being deinitialized") } } var john: Person? = Person(name: "John") var unit4A: Apartment? = Apartment(unit: "4A") john?.apartment = unit4A // Ak by Apartment mal silnú referenciu na Person unit4A?.tenant = john // Slabá referencia // Po zrušení silných odkazov budú objekty de-inicializované john = nil unit4A = nil // Výstup: "John is being deinitialized", "Apartment 4A is being deinitialized" // Ak by tenant bola silná referencia, došlo by k úniku pamäti (strong cycle) - Deklaruje sa pomocou kľúčového slova
-
Bezstarostná referencia (Unowned Reference):
- Deklaruje sa pomocou kľúčového slova
unowned. - Podobne ako slabá referencia, nezvyšuje počítadlo odkazov na objekt.
- Používa sa na prevenciu
strong reference cycles. - Na rozdiel od
weak, nie je voliteľná (Optional) a predpokladá, že objekt, na ktorý odkazuje, bude existovať počas celého "životného cyklu" bezstarostnej referencie. - Ak je objekt, na ktorý odkazuje
unownedreferencia, de-inicializovaný skôr, než sa stane neplatnou, nastane runtime chyba. - Hodí sa do situácií, keď jeden objekt vždy existuje, kým existuje iný s ním spojený, ale nie naopak (napríklad "rodič-dieťa", kde rodič vlastní dieťa, ale dieťa ne vlastní rodiča silno).
class Customer { let name: String var card: CreditCard? init(name: String) { self.name = name } deinit { print("\(name) is being deinitialized") } } class CreditCard { let number: Int unowned let customer: Customer // Bezstarostná referencia init(number: Int, customer: Customer) { self.number = number self.customer = customer // Priradenie bezstarostnej referencie je bezpečné v init } deinit { print("Card #\(number) is being deinitialized") } } var john: Customer? = Customer(name: "John Doe") john?.card = CreditCard(number: 1234_5678_9012_3456, customer: john!) // Zrušenie silnej referencie na Customer john = nil // Výstup: "John Doe is being deinitialized", "Card #1234567890123456 is being deinitialized" // Bezstarostná referencia na customer v CreditCard bola platná, kým customer existoval. // Ak by CreditCard žil dlhšie ako Customer a pokúsili by sme sa odkazovať na customer cez bezstarostnú referenciu, nastala by chyba. - Deklaruje sa pomocou kľúčového slova
Kľúčový rozdiel medzi weak a unowned:
weak: objekt môže byťnil. Používajte, keď životnosť objektov nie je striktne previazaná (jeden môže existovať bez druhého).unowned: objekt nemôže byťnilpo inicializácii. Používa sa, keď ste si istí, že odkazovaný objekt bude existovať aspoň dovtedy, kým existuje odkazujúci objekt.