Sobes.tech
Middle

Зашто је потребан тип референци unowned?

sobes.tech АИ

Одговор од АИ

unowned reference su potrebni za rešavanje cikličnih referenci (retain cycles) između objekata, kada oba objekta imaju snažnu referencu na drugog, ali jedan od njih ima kraći ili jednak životni ciklus u poređenju sa drugim.

unowned se koristi kada je poznato da referencirani objekat neće biti nil tokom celog životnog veka objekta koji sadrži referencu. Za razliku od weak, kod unowned pristupa referenci se ne koristi Optional. Ako objekat na koji se odnosi unowned bude deallociran pre nego što objekat sa unowned referencom bude deallociran, doći će do crash-a.

Primer upotrebe u zatvaranjima:

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

    init(name: String) {
        self.name = name
        print("\(name) se inicijalizuje")
    }

    deinit {
        print("\(name) se deinitializuje")
    }
}

class Apartment {
    let unit: String
    // Koristimo `unowned`, jer je poznato da
    // Apartment ne može da postoji bez Person
    // (u ovom kontekstu). Person može biti nil,
    // ali ako Apartment postoji, i Person postoji.
    unowned let tenant: Person

    init(unit: String, tenant: Person) {
        self.unit = unit
        self.tenant = tenant
        print("Apartment \(unit) se inicijalizuje")
    }

    deinit {
        print("Apartment \(unit) se deinitializuje")
    }
}

var john: Person?
var unit4A: Apartment?

john = Person(name: "John Appleseed")
// U ovom primeru, tenant može biti nil, pa je `unowned`
unit4A = Apartment(unit: "4A", tenant: john!)

john!.apartment = unit4A

// Prekidaćemo snažne reference da bismo proverili deallocaciju
john = nil
unit4A = nil

U ovom primeru, Person ima snažnu referencu na Apartment (var apartment: Apartment?). Apartment bi mogao imati snažnu referencu na Person, što bi dovelo do cikličke reference. Međutim, jer u ovom kontekstu Apartment logički ne može postojati bez Person (koji ga iznajmljuje), veza od Apartment ka Person se pravi sa unowned. Tako, kada postavimo john = nil, Person se deallocira, a zatim (pošto nema snažnih referenci na Apartment) i Apartment se deallocira.

Glavne razlike u odnosu na weak:

  • Životni ciklus: unowned se koristi kada referencirani objekat ima isti ili duži životni ciklus. weak se koristi kada referencirani objekat može biti deallociran ranije.
  • Optional: unowned nije Optional (osim ako nije deklarisan kao unowned optional). weak je uvek Optional.
  • Bezbednost: Pristup svojstvu sa unowned referencom na već deallociran objekat će izazvati crash. Pristup weak referenci će vratiti nil.

Dakle, unowned je ne-posedujuća (non-owning) referenca, koja se koristi kada je garantovano postojanje referenciranog objekta dok postoji objekat sa unowned referencom.