Sobes.tech
Middle

Ποιος είναι ο σκοπός του τύπου αναφορών unowned;

sobes.tech AI

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

Οι αναφορές unowned είναι απαραίτητες για την επίλυση κυκλικών αναφορών (retention cycles) μεταξύ αντικειμένων, όταν και τα δύο αντικείμενα έχουν ισχυρή αναφορά το ένα στο άλλο, αλλά ένα από αυτά έχει μικρότερο ή ίσο κύκλο ζωής.

Το unowned χρησιμοποιείται όταν γνωρίζουμε ότι το αντικείμενο που αναφέρεται δεν θα είναι nil κατά τη διάρκεια ολόκληρης της ζωής του αντικειμένου που περιέχει την αναφορά. Σε αντίθεση με το weak, η πρόσβαση σε μια unowned αναφορά δεν χρησιμοποιεί Optional. Αν το αντικείμενο στο οποίο αναφέρεται το unowned διαγραφεί πριν από το αντικείμενο που περιέχει την αναφορά, θα προκληθεί crash.

Παράδειγμα χρήσης σε closures:

class Person {
    let name: String
    var apartment: Apartment?

    init(name: String) {
        self.name = name
        print("\(name) αρχίζει")
    }

    deinit {
        print("\(name) τελειώνει")
    }
}

class Apartment {
    let unit: String
    // Χρησιμοποιούμε `unowned` επειδή γνωρίζουμε ότι
    // το Apartment δεν μπορεί να υπάρξει χωρίς το Person
    // (σε αυτό το πλαίσιο). Το Person μπορεί να είναι nil,
    // αλλά αν το Apartment υπάρχει, το ίδιο και το Person.
    unowned let tenant: Person

    init(unit: String, tenant: Person) {
        self.unit = unit
        self.tenant = tenant
        print("Διαμέρισμα \(unit) αρχίζει")
    }

    deinit {
        print("Διαμέρισμα \(unit) τελειώνει")
    }
}

var john: Person?
var unit4A: Apartment?

john = Person(name: "John Appleseed")
// Σε αυτό το παράδειγμα, το tenant μπορεί να είναι nil, επομένως
// χρησιμοποιούμε μια αναφορά unowned
unit4A = Apartment(unit: "4A", tenant: john!)

john!.apartment = unit4A

// Διακόπτουμε τις ισχυρές αναφορές για να ελέγξουμε την αποδέσμευση
john = nil
unit4A = nil

Σε αυτό το παράδειγμα, ο Person έχει ισχυρή αναφορά σε Apartment (var apartment: Apartment?). Το Apartment θα μπορούσε να έχει ισχυρή αναφορά σε Person, δημιουργώντας έναν κύκλο. Ωστόσο, σε αυτό το πλαίσιο, το Apartment δεν μπορεί να υπάρξει χωρίς το Person (που το ενοικιάζει), οπότε η αναφορά από Apartment σε Person γίνεται unowned. Έτσι, όταν ορίζουμε john = nil, ο Person αποδεσμεύεται, και στη συνέχεια (καθώς δεν υπάρχουν ισχυρές αναφορές σε Apartment) και το Apartment αποδεσμεύεται.

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

  • Κύκλος ζωής: Το unowned χρησιμοποιείται όταν το αντικείμενο που αναφέρεται έχει ίδιο ή μεγαλύτερο κύκλο ζωής. Το weak χρησιμοποιείται όταν το αντικείμενο που αναφέρεται μπορεί να διαγραφεί νωρίτερα.
  • Optional: Το unowned δεν είναι Optional (εκτός αν δηλωθεί ως unowned optional). Το weak είναι πάντα Optional.
  • Ασφάλεια: Η πρόσβαση σε μια ιδιότητα με αναφορά unowned σε ήδη διαγραφέν αντικείμενο θα προκαλέσει crash. Η πρόσβαση σε weak αναφορά θα επιστρέψει nil.

Επομένως, το unowned είναι μια μη-ιδιοκτησιακή (non-owning) αναφορά, που χρησιμοποιείται όταν διασφαλίζεται η ύπαρξη του αναφερόμενου αντικειμένου όσο υπάρχει το αντικείμενο με την unowned αναφορά.