Middle
Koje vrste referenci postoje u Swift-u?
sobes.tech АИ
Одговор од АИ
U Swiftu postoje tri glavne vrste referenci na instance klasa:
-
Snažna referenca (Strong Reference):
- Ovo je podrazumevani tip reference.
- Snažna referenca povećava brojač referenci objekta.
- Objekt neće biti oslobođen iz memorije dok postoji bar jedna snažna referenca na njega.
- Glavni razlog za curenje memorije u slučaju cikličnih snažnih referenci (
strong reference cycles).
class Person { let name: String init(name: String) { self.name = name } deinit { print("\(name) se oslobađa") } } var reference1: Person? = Person(name: "John") // reference1 je sada snažna referenca, brojač referenci za Person se povećava -
Slaba referenca (Weak Reference):
- Deklariše se ključnom rečju
weak. - Slaba referenca ne povećava brojač referenci objekta.
- Koristi se za sprečavanje
strong reference cycles. - Uvek je opcionalna (
Optional), jer objekat na koji ukazuje može biti deinitializovan u bilo kom trenutku. Pri deinitializaciji, slaba referenca automatski postajenil.
class Apartment { let unit: String weak var tenant: Person? // Slaba referenca init(unit: String) { self.unit = unit } deinit { print("Stan \(unit) se oslobađa") } } var john: Person? = Person(name: "John") var unit4A: Apartment? = Apartment(unit: "4A") john?.apartment = unit4A // Ako je Apartment imao snažnu referencu na John unit4A?.tenant = john // Slaba referenca // Nakon brisanja snažnih referenci, objekti će biti deinitializovani john = nil unit4A = nil // Izlaz: "John se oslobađa", "Stan 4A se oslobađa" // Ako je tenant bio snažna referenca, došlo bi do curenja memorije (strong cycle) - Deklariše se ključnom rečju
-
Nepovezana referenca (Unowned Reference):
- Deklariše se ključnom rečju
unowned. - Kao i slaba referenca, ne povećava brojač referenci objekta.
- Takođe se koristi za sprečavanje
strong reference cycles. - Za razliku od
weak, nije opcionalna (Optional) i pretpostavlja da će objekat na koji ukazuje postojati tokom celog "životnog veka" nepovezane reference. - Ako objekat na koji ukazuje
unownedreferenca bude deinitializovan pre nego štounownedreferenca postane nevažeća, doći će do greške u izvršenju (runtime error). - Pogodno je za situacije kada jedan objekat uvek postoji dok postoji drugi povezani objekat (npr. odnos "roditelj- dete", gde roditelj poseduje dete, ali dete ne poseduje roditelja snažno).
class Customer { let name: String var card: CreditCard? init(name: String) { self.name = name } deinit { print("\(name) se oslobađa") } } class CreditCard { let number: Int unowned let customer: Customer // Nepovezana referenca init(number: Int, customer: Customer) { self.number = number self.customer = customer // Dodeljivanje nepovezane reference je bezbedno u init } deinit { print("Karta #\(number) se oslobađa") } } var john: Customer? = Customer(name: "John Doe") john?.card = CreditCard(number: 1234_5678_9012_3456, customer: john!) // Brisanje snažne reference na Customer john = nil // Izlaz: "John Doe se oslobađa", "Karta #1234567890123456 se oslobađa" // Nepovezana referenca na customer u CreditCard je bila važeća dok je customer postojao. // Ako bi CreditCard trajao duže od Customer i pokušali bismo da pristupimo customer-u putem nepovezane reference, došlo bi do greške. - Deklariše se ključnom rečju
Ključna razlika između weak i unowned:
weak: objekat može bitinil. Koristite kada životni vek objekata nije strogo povezan (jedan može postojati bez drugog).unowned: objekat ne može bitinilnakon inicijalizacije. Koristite kada ste sigurni da će referencirani objekat postojati najmanje dok postoji objekat koji ga referencira.