Sobes.tech
Middle

Kas yra unowned?

sobes.tech AI

Atsakymas iš AI

unowned — tai raktas žodis Swift kalbantis silpną nuorodą. Jis naudojamas, kai du objektai turi stiprią ryšį ir jų gyvavimo ciklai priklauso vienas nuo kito, tačiau norime išvengti ciklinių nuorodų, kurios gali trukdyti atlaisvinti atmintį.

Pagrindinės savybės ir skirtumai nuo weak:

  • Neoptinalus: unowned nuoroda garantuotai nebus nil viso objekto gyvavimo metu, į kurį ji nuoroda.
  • Stipri ryšys: Naudojama, kai vienas objektas valdo kitą ir jie visada egzistuoja kartu.
  • Atlaisvinus: Jei objektas, į kurį nuoroda unowned nuoroda, atlaisvinamas iš atminties iki nuorodos naudojimo, tai sukels programos avariją (runtime error). Reikia įsitikinti, kad objektas, į kurį nuoroda, egzistuoja ilgiau nei pati nuoroda.
  • Naudojimas: Dažniausiai naudojama delegatams, kai delegatas visada egzistuoja ilgiau nei objektas, kuris jį kviečia, arba uždarymuose, siekiant išvengti ciklinių nuorodų į self, kai uždarymas neįtraukia stiprios nuorodos į self.

Pavyzdys naudojimo uždaryme:

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

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

    func setupClosure() {
        closure = { [unowned self] in // Naudojant unowned self
            print("My name is \(self.name)")
        }
    }

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

Pavyzdys naudojimo delegatui (nors weak dažniau naudojama delegatams, unowned taip pat įmanoma, jei delegatas garantuotai gyvena ilgiau):

// swift
protocol MyDelegate: AnyObject { // AnyObject reikalauja nuorodinio tipo
    func doSomething()
}

class DataSource {
    unowned var delegate: MyDelegate // unowned nuoroda į delegatą

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

    func performAction() {
        delegate.doSomething()
    }

    deinit {
        print("DataSource deinitialized")
    }
}

class MyController: MyDelegate {
    var dataSource: DataSource?

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

    func doSomething() {
        print("Delegate method called")
    }

    deinit {
        print("MyController deinitialized")
    }
}

Pasirinkimas tarp weak ir unowned priklauso nuo to, ar nuoroda yra pasirinktinė ir ar objektas, į kurį ji nuoroda, egzistuoja iki pat nuorodos gyvavimo pabaigos. Jei yra tikimybė, kad objektas gali būti atlaisvintas iki nuorodos naudojimo, reikėtų naudoti weak. Jei garantuojama, kad objektas egzistuoja, ir nuoroda neturėtų būti pasirinktinė, galima naudoti unowned.