Middle
Kokie nuorodų tipai yra Swift?
sobes.tech AI
Atsakymas iš AI
Swift turi trys pagrindiniai nuorodų tipai į klasių pavyzdžius:
-
Stipri nuoroda (Strong Reference):
- Tai numatytasis nuorodų tipas.
- Stipri nuoroda padidina objekto nuorodų skaitiklį.
- Objektas nebus atlaisvintas iš atminties, kol turės bent vieną stiprią nuorodą.
- Pagrindinė priežastis – ciklinės stiprios nuorodos (
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 dabar stipri nuoroda, `Person` nuorodų skaitiklis didėja -
Silpna nuoroda (Weak Reference):
- Deklaruojama naudojant žodį
weak. - Silpna nuoroda nesudaro objekto nuorodų skaitiklio padidėjimo.
- Naudojama siekiant išvengti
strong reference cycles. - Visada yra pasirinktinė (
Optional), nes nuoroda į objektą, į kurį nurodo silpna nuoroda, gali būti deinitializuota bet kuriuo metu. Deinitializacijos metu silpna nuoroda automatiškai tampanil.
class Apartment { let unit: String weak var tenant: Person? // Silpna nuoroda 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 // Jei `Apartment` turėtų stiprią nuorodą į `Person` unit4A?.tenant = john // Silpna nuoroda // Po stiprių nuorodų atšaukimo, objektai bus deinitializuoti john = nil unit4A = nil // Išvestis: "John is being deinitialized", "Apartment 4A is being deinitialized" // Jei `tenant` būtų stipri nuoroda, įvyktų atminties nutekėjimas (strong cycle) - Deklaruojama naudojant žodį
-
Nepageidaujama nuoroda (Unowned Reference):
- Deklaruojama naudojant žodį
unowned. - Panaši į silpną nuorodą, nes nesudaro objekto nuorodų skaitiklio padidėjimo.
- Naudojama siekiant išvengti
strong reference cycles. - Skirtingai nuo
weak, nėra pasirinktinė (Optional) ir turi būti tikima, kad nuoroda į objektą egzistuos viso objekto gyvavimo ciklo metu. - Jei
unownednuoroda nurodo į objektą, kuris buvo deinitializuotas, įvyksta klaida vykdymo metu (runtime error). - Tinka situacijoms, kai vienas objektas visada egzistuoja, kol egzistuoja kitas susijęs objektas, bet ne atvirkščiai (pavyzdžiui, "tėvas-vaikas", kur tėvas valdo vaiką, bet vaikas nevaldo tėvo stipriai).
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 // Nepageidaujama nuoroda init(number: Int, customer: Customer) { self.number = number self.customer = customer // Inicijavimo metu saugu } deinit { print("Card #\(number) is being deinitialized") } } var john: Customer? = Customer(name: "John Doe") john?.card = CreditCard(number: 1234_5678_9012_3456, customer: john!) // Stiprios nuorodos į `Customer` išjungimas john = nil // Išvestis: "John Doe is being deinitialized", "Card #1234567890123456 is being deinitialized" // `CreditCard` viduje `customer` nuoroda buvo galiojanti, kol `customer` egzistavo. // Jei `CreditCard` gyventų ilgiau nei `Customer` ir bandytume pasiekti `customer` per `unowned` nuorodą, įvyktų klaida. - Deklaruojama naudojant žodį
Pagrindinis skirtumas tarp weak ir unowned:
weak: objektas gali būtinil. Naudokite, kai objektų gyvavimo trukmė nėra griežtai susieta (vienas gali egzistuoti be kito).unowned: objektas negali būtinilpo inicializacijos. Naudokite, kai esate tikras, kad nuoroda į objektą egzistuos bent iki tol, kol egzistuos objektą nurodantis objektas.