Sobes.tech
Middle

Τι είναι unowned;

sobes.tech AI

Απάντηση από AI

unowned — είναι μια λέξη-κλειδί στη Swift για τον ορισμό μιας αδύναμης αναφοράς. Χρησιμοποιείται όταν δύο αντικείμενα έχουν μια ισχυρή σχέση και οι κύκλοι ζωής τους εξαρτώνται το ένα από το άλλο, αλλά θέλουμε να αποφύγουμε κυκλικές αναφορές που θα μπορούσαν να εμποδίσουν την απελευθέρωση της μνήμης.

Βασικά χαρακτηριστικά και διαφορές με το weak:

  • Μη προαιρετικό: Η αναφορά unowned δεν θα γίνει nil κατά τη διάρκεια ζωής του αντικειμένου στο οποίο αναφέρεται.
  • Ισχυρή σχέση: Χρησιμοποιείται όταν ένα αντικείμενο κατέχει ένα άλλο και και τα δύο υπάρχουν πάντα μαζί.
  • Κατά την απελευθέρωση: Αν το αντικείμενο στο οποίο αναφέρεται η unowned αναφορά απελευθερωθεί από τη μνήμη πριν χρησιμοποιηθεί η αναφορά, αυτό θα οδηγήσει σε σφάλμα κατά την εκτέλεση (runtime error). Πρέπει να διασφαλίσουμε ότι το αντικείμενο στο οποίο αναφέρεται υπάρχει περισσότερο χρόνο από τη δική του αναφορά.
  • Εφαρμογή: Χρησιμοποιείται συχνά για τους διαχειριστές (delegates), όταν ο διαχειριστής υπάρχει πάντα περισσότερο χρόνο από το αντικείμενο που τον καλεί, ή σε closures για να αποφύγουμε κυκλικές αναφορές στο self, όταν το closure δεν καταγράφει ισχυρή αναφορά στο self.

Παράδειγμα χρήσης σε ένα closure:

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

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

    func setupClosure() {
        closure = { [unowned self] in // Χρήση του unowned self
            print("Το όνομά μου είναι \(self.name)")
        }
    }

    deinit {
        print("\(name) απελευθερώθηκε")
    }
}

Παράδειγμα χρήσης για έναν διαχειριστή (αν και το weak χρησιμοποιείται συχνότερα για τους διαχειριστές, το unowned είναι επίσης δυνατό αν ο διαχειριστής εγγυάται ότι θα ζήσει περισσότερο):

// swift
protocol MyDelegate: AnyObject { // Το AnyObject απαιτεί τύπο αναφοράς
    func doSomething()
}

class DataSource {
    unowned var delegate: MyDelegate // αναφορά `unowned` στον διαχειριστή

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

    func performAction() {
        delegate.doSomething()
    }

    deinit {
        print("DataSource απελευθερώθηκε")
    }
}

class MyController: MyDelegate {
    var dataSource: DataSource?

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

    func doSomething() {
        print("Κλήση μεθόδου διαχειριστή")
    }

    deinit {
        print("MyController απελευθερώθηκε")
    }
}

Η επιλογή μεταξύ weak και unowned εξαρτάται από το αν η αναφορά είναι προαιρετική και αν το αντικείμενο στο οποίο αναφέρεται υπάρχει εγγυημένα μέχρι το τέλος της ζωής της αναφοράς. Αν υπάρχει πιθανότητα το αντικείμενο να απελευθερωθεί πριν από τη χρήση της αναφοράς, πρέπει να χρησιμοποιείται το weak. Αν η ύπαρξη είναι εγγυημένη και η αναφορά δεν πρέπει να είναι προαιρετική, μπορεί να χρησιμοποιηθεί το unowned.