Sobes.tech
Middle

Mi az az unowned?

sobes.tech MI

Válasz az MI-től

Az unowned a Swift kulcsszava a gyenge (weak) hivatkozás deklarálására. Akkor használjuk, amikor két objektum erős kapcsolatban áll, és életciklusuk egymástól függ, de el akarjuk kerülni a ciklikus hivatkozásokat, amelyek megakadályozhatják a memória felszabadítását.

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

  • Nem opcionális: Az unowned hivatkozás nem lesz nil az objektum életciklusa során, amelyre hivatkozik.
  • Erős kapcsolat: Akkor használjuk, amikor egy objektum másikat birtokol, és mindkettő mindig együtt létezik.
  • Felszabadításkor: Ha az objektum, amelyre az unowned hivatkozás utal, a memória felszabadítása előtt kerül felszabadításra, ez futási hibát (runtime error) eredményez. Biztosnak kell lennünk abban, hogy a hivatkozott objektum hosszabb ideig létezik, mint maga a hivatkozás.
  • Alkalmazás: Gyakran használják delegáltakhoz, amikor a delegált mindig hosszabb ideig létezik, mint a hívó objektum, vagy closures-ben, hogy elkerüljék a ciklikus hivatkozásokat self-re, amikor a closure nem erős hivatkozást foglal magába self-re.

Példa használatra closure-ben:

// swift
class MyClass {
    var name: String
    var closure: (() -> Void)?

    init(name: String) {
        self.name = name
    }

    func setupClosure() {
        closure = { [unowned self] in // unowned self használata
            print("Az én nevem \(self.name)")
        }
    }

    deinit {
        print("\(name) felszabadult")
    }
}

Delegált példában (bár a weak gyakrabban használatos delegáltaknál, az unowned szintén lehetőség, ha a delegált garantáltan hosszabb ideig él):

// swift
protocol MyDelegate: AnyObject { // Az `AnyObject` referencia típus szükséges
    func doSomething()
}

class DataSource {
    unowned var delegate: MyDelegate // unowned referencia a delegáltra

    init(delegate: MyDelegate) {
        self.delegate = delegate
    }

    func performAction() {
        delegate.doSomething()
    }

    deinit {
        print("DataSource felszabadult")
    }
}

class MyController: MyDelegate {
    var dataSource: DataSource?

    override init() {
        super.init()
        dataSource = DataSource(delegate: self)
    }

    func doSomething() {
        print("Delegált metódus hívva")
    }

    deinit {
        print("MyController felszabadult")
    }
}

A weak és unowned közötti választás attól függ, hogy a referencia opcionális-e, és az objektum, amelyre hivatkozik, garantáltan létezik-e a referencia életének végéig. Ha fennáll annak a lehetősége, hogy az objektum a referencia használata előtt felszabadul, akkor a weak-et kell használni. Ha a létezés garantált, és a referencia nem lehet opcionális, akkor az unowned használható.