Sobes.tech
Middle

Mis on unowned?

sobes.tech AI

Vastus AI-lt

unowned — see on võtmesõna Swiftis nõrga viite deklaratsiooniks. Seda kasutatakse, kui kaks objekti on tugeva sidemega ja nende elutsüklid sõltuvad üksteisest, kuid soovime vältida tsüklilisi viiteid, mis võivad takistada mälu vabastamist.

Peamised omadused ja erinevused weak-iga:

  • Valikuline mitte: unowned viide ei muutu nil-iks kogu objekti eluea jooksul, millele see viitab.
  • Tugev side: Kasutatakse, kui üks objekt omab teist ja nad eksisteerivad alati koos.
  • Vabastamisel: Kui unowned viitega viidatud objekt vabastatakse mälust enne viite kasutamist, põhjustab see rakenduse krahhi (runtime error). Tuleb veenduda, et viidatud objekt eksisteerib kauem kui viide ise.
  • Kasutus: Enamasti kasutatakse delegeerijate puhul, kui delegeerija eksisteerib alati kauem kui objekt, mis seda kutsub, või suletud funktsioonides, et vältida tsüklilisi viiteid self-ile, kui suletud funktsioon ei haarata tugevat viidet self-ile.

Näide kasutamisest suletud funktsioonis:

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

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

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

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

Näide delegeerija kasutamisest (kuigi weak kasutatakse sageli delegeerijate puhul, unowned on samuti võimalik, kui delegeerija garanteeritult elab kauem):

// swift
protocol MyDelegate: AnyObject { // AnyObject nõuab viit tüüpi
    func doSomething()
}

class DataSource {
    unowned var delegate: MyDelegate // unowned viide delegeerijale

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

Valik weak ja unowned vahel sõltub sellest, kas viide on valikuline ja kas objekt, millele see viitab, eksisteerib viite elu lõpuni. Kui on tõenäoline, et objekt võib enne viite kasutamist vabastada, tuleks kasutada weak. Kui garantiiga on, et objekt eksisteerib ja viide ei peaks olema valikuline, võib kasutada unowned.