Sobes.tech
Middle

Mire való az unowned típusú hivatkozás?

sobes.tech MI

Válasz az MI-től

Az unowned hivatkozások akkor szükségesek, amikor ciklikus hivatkozások (retain cycle-ek) alakulnak ki objektumok között, amikor mindkét objektum erős hivatkozással rendelkezik egymásra, de az egyik objektum élettartama rövidebb vagy egyenlő a másikéval.

Az unowned akkor használatos, amikor ismert, hogy a hivatkozott objektum nem lesz nil az egész életciklusa során az objektumnak, amely tartalmazza a hivatkozást. Ellentétben a weak-kel, az unowned-nál nem használunk Optional-t a hozzáféréskor. Ha az objektum, amelyre az unowned hivatkozik, deallocálódik azelőtt, hogy az unowned hivatkozású objektum deallocálódna, akkor crash történik.

Példa használatra zárványokban:

class Person {
    let name: String
    var apartment: Apartment?

    init(name: String) {
        self.name = name
        print("\(name) is being initialized")
    }

    deinit {
        print("\(name) is being deinitialized")
    }
}

class Apartment {
    let unit: String
    // `unowned`-et használunk, mivel ismert, hogy
    // az Apartment nem létezhet Person nélkül
    // (ebben a kontextusban). A Person lehet nil,
    // de ha az Apartment létezik, akkor a Person is létezik.
    unowned let tenant: Person

    init(unit: String, tenant: Person) {
        self.unit = unit
        self.tenant = tenant
        print("Apartment \(unit) is being initialized")
    }

    deinit {
        print("Apartment \(unit) is being deinitialized")
    }
}

var john: Person?
var unit4A: Apartment?

john = Person(name: "John Appleseed")
// Ebben a példában a tenant lehet nil, ezért az `unowned` opcionális
unit4A = Apartment(unit: "4A", tenant: john!)

john!.apartment = unit4A

// Erős hivatkozások megszakítása a deallokáció ellenőrzéséhez
john = nil
unit4A = nil

Ebben a példában a Person erős hivatkozással rendelkezik az Apartment-re (var apartment: Apartment?). Az Apartment erős hivatkozással rendelkezhet a Person-re, ami ciklust eredményezne. Azonban, mivel ebben a példában az Apartment logikailag nem létezhet Person nélkül (aki bérli), az Apartment-t a Person-hez kötjük unowned-ként. Így, amikor a john = nil-t végrehajtjuk, a Person deallocálódik, és mivel nincs erős hivatkozás az Apartment-re, az is deallocálódik.

Főbb különbségek a weak-hez képest:

  • Élettartam: Az unowned akkor használatos, amikor a hivatkozott objektumnak ugyanakkora vagy hosszabb élettartama van. A weak akkor, amikor a hivatkozott objektum korábban deallocálódhat.
  • Optional: Az unowned nem opcionális (kivéve, ha unowned optional-ként van deklarálva). A weak mindig Optional.
  • Biztonság: Az unowned hivatkozás hozzáférése egy már deallocált objektumhoz crash-t eredményez. A weak hozzáférés nil-t ad.

Összefoglalva, az unowned egy nem-ownership (nem tulajdonló) hivatkozás, amely akkor használatos, amikor garantált az objektum létezése addig, amíg az unowned hivatkozás létezik.