Sobes.tech
Middle

Kas ir unowned?

sobes.tech AI

Atbilde no AI

unowned — tas ir atslēgas vārds Swift, lai deklarētu vājo atsauci. To izmanto, ja divi objekti ir stipra saikne un to dzīves cikli ir atkarīgi viens no otra, bet mēs vēlamies izvairīties no cikliskām atsaucēm, kas var traucēt atmiņas brīvu atbrīvošanu.

Galvenās īpašības un atšķirības no weak:

  • Nepieciešama: unowned atsauce garantēti nebūs nil visu objekta dzīves laiku, uz kuru tā atsaucas.
  • Stipra saikne: Izmanto, ja viens objekts pieder citam, un tie vienmēr pastāv kopā.
  • Atbrīvojot: Ja objekts, uz kuru atsaucas unowned atsauce, tiek atbrīvots no atmiņas pirms atsauces izmantošanas, tas novedīs pie lietojumprogrammas avārijas (runtime error). Jābūt pārliecinātam, ka objekts, uz kuru atsaucas, pastāv ilgāk nekā pati atsauce.
  • Lietošana: Bieži tiek izmantots delegātu gadījumā, ja delegāts vienmēr pastāv ilgāk nekā objekts, kas to izsauc, vai slēdžos, lai izvairītos no cikliskām atsaucēm uz self, kad slēdzis neiekļauj stipru atsauci uz self.

Piemērs lietošanā slēdžos:

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

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

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

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

Piemērs ar delegātu (lai gan weak biežāk tiek izmantots delegātiem, unowned ir arī iespējams, ja delegāts garantēti ilgāk dzīvos):

// swift
protocol MyDelegate: AnyObject { // AnyObject prasa atsauces tipu
    func doSomething()
}

class DataSource {
    unowned var delegate: MyDelegate // `unowned` atsauce uz delegātu

    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")
    }
}

Izvēle starp weak un unowned ir atkarīga no tā, vai atsauce ir izvēles un vai objekts, uz kuru tā atsaucas, pastāv līdz dzīves beigām. Ja ir iespēja, ka objekts var tikt atbrīvots pirms atsauces izmantošanas, jāizmanto weak. Ja ir garantija, ka objekts pastāv, un atsauce nedrīkst būt izvēles, var izmantot unowned.