Sobes.tech
Middle

Milyen típusú hivatkozások léteznek Swift-ben?

sobes.tech MI

Válasz az MI-től

Swift-ben három fő típusú hivatkozás létezik osztálypéldányokra:

  1. Erős hivatkozás (Strong Reference):

    • Ez az alapértelmezett hivatkozástípus.
    • Az erős hivatkozás növeli az objektum hivatkozásszámlálóját.
    • Az objektum nem kerül felszabadításra a memóriából, amíg legalább egy erős hivatkozás létezik rá.
    • A fő ok a memória szivárgására ciklikus erős hivatkozások esetén (strong reference cycles).
    class Person {
        let name: String
        init(name: String) { self.name = name }
        deinit { print("\(name) felszabadul") }
    }
    
    var reference1: Person? = Person(name: "John")
    // reference1 most egy erős hivatkozás, növeli a Person hivatkozásszámát
    
  2. Gyenge hivatkozás (Weak Reference):

    • A weak kulcsszóval deklarálva.
    • A gyenge hivatkozás nem növeli az objektum hivatkozásszámát.
    • A strong reference cycles megelőzésére használják.
    • Mindig opcionális (Optional), mert a hivatkozott objektum bármikor deinitializálódhat. A deinitializáláskor a gyenge hivatkozás automatikusan nil lesz.
    class Apartment {
        let unit: String
        weak var tenant: Person? // Gyenge hivatkozás
        init(unit: String) { self.unit = unit }
        deinit { print("Lakás \(unit) felszabadul") }
    }
    
    var john: Person? = Person(name: "John")
    var unit4A: Apartment? = Apartment(unit: "4A")
    
    john?.apartment = unit4A // Ha az Apartment erős hivatkozással rendelkezne John-ra
    unit4A?.tenant = john   // Gyenge hivatkozás
    
    // Az erős hivatkozások törlése után az objektumok deinitializálódnak
    john = nil
    unit4A = nil
    // Kimenet: "John felszabadul", "Lakás 4A felszabadul"
    // Ha a tenant erős hivatkozás lett volna, memória szivárgás lépett volna fel (strong cycle)
    
  3. Független hivatkozás (Unowned Reference):

    • A unowned kulcsszóval deklarálva.
    • Hasonlóan a gyenge hivatkozáshoz, nem növeli az objektum hivatkozásszámát.
    • Szintén a strong reference cycles megelőzésére használják.
    • A weak-hez képest nem opcionális (Optional) és feltételezi, hogy a hivatkozott objektum a "tartam" során létezik.
    • Ha a unowned hivatkozás által hivatkozott objektum deinitializálódik, mielőtt a hivatkozás érvénytelenné válna, futási hiba történik (runtime error).
    • Olyan helyzetekben alkalmas, amikor egy objektum mindig létezik, amíg egy másik objektum is (pl. "szülő-gyermek" kapcsolat, ahol a szülő birtokolja a gyermeket, de a gyermek nem birtokolja a szülőt erősen).
    class Customer {
        let name: String
        var card: CreditCard?
        init(name: String) { self.name = name }
        deinit { print("\(name) felszabadul") }
    }
    
    class CreditCard {
        let number: Int
        unowned let customer: Customer // Független hivatkozás
    
        init(number: Int, customer: Customer) {
            self.number = number
            self.customer = customer // Az init-ben történő független hivatkozás hozzárendelése biztonságos
        }
        deinit { print("Kártya #\(number) felszabadul") }
    }
    
    var john: Customer? = Customer(name: "John Doe")
    john?.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
    
    // Erős hivatkozás törlése a Customer-re
    john = nil
    // Kimenet: "John Doe felszabadul", "Kártya #1234567890123456 felszabadul"
    // A CreditCard-ben lévő független hivatkozás a customer-re akkor volt érvényes, amíg a customer létezett.
    // Ha a CreditCard tovább élt volna, mint a Customer, és megpróbálnánk hozzáférni a customer-hez a független hivatkozáson keresztül, hiba lépett volna fel.
    

Fő különbség a weak és az unowned között:

  • weak: az objektum nil lehet. Használja, amikor az objektumok élettartama nem szigorúan összekapcsolt (egyik létezhet a másik nélkül).
  • unowned: az objektum nem lehet nil azután, hogy inicializálták. Használja, amikor biztos benne, hogy a hivatkozott objektum legalább addig létezik, amíg a hivatkozó objektum létezik.