Sobes.tech
Middle

Koje vrste referenci postoje u Swift-u?

sobes.tech АИ

Одговор од АИ

U Swiftu postoje tri glavne vrste referenci na instance klasa:

  1. 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
    
  2. 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 postaje nil.
    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)
    
  3. 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 unowned referenca bude deinitializovan pre nego što unowned referenca 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.
    

Ključna razlika između weak i unowned:

  • weak: objekat može biti nil. Koristite kada životni vek objekata nije strogo povezan (jedan može postojati bez drugog).
  • unowned: objekat ne može biti nil nakon inicijalizacije. Koristite kada ste sigurni da će referencirani objekat postojati najmanje dok postoji objekat koji ga referencira.