Sobes.tech
Middle

Ποιοι τύποι αναφορών υπάρχουν στο Swift;

sobes.tech AI

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

Υπάρχουν τρεις βασικοί τύποι αναφορών στη Swift:

  1. Strong Reference (Ισχυρή Αναφορά):

    • Αυξάνει τον μετρητή αναφορών του αντικειμένου.
    • Αποτρέπει την απελευθέρωση του αντικειμένου όσο υπάρχει τουλάχιστον μία ισχυρή αναφορά.
    • Είναι ο προεπιλεγμένος τύπος αναφοράς στη Swift.
    • Προκαλεί κυκλικές αναφορές.
  2. Weak Reference (Ασθενής Αναφορά):

    • Δεν αυξάνει τον μετρητή αναφορών.
    • Επιτρέπει την απελευθέρωση του αντικειμένου αν δεν υπάρχουν ισχυρές αναφορές.
    • Ορίζεται με τη λέξη-κλειδί weak.
    • Πάντα είναι προαιρετική (Optional), καθώς το αντικείμενο μπορεί να είναι nil.
    • Χρησιμοποιείται για την αποφυγή κυκλικών αναφορών.
    class Person {
        let name: String
        weak var apartment: Apartment? // Ασθενής αναφορά
        init(name: String) {
            self.name = name
        }
        deinit { print("\(name) απελευθερώθηκε") }
    }
    
    class Apartment {
        let unit: String
        var tenant: Person? // Συνήθης ισχυρή αναφορά
        init(unit: String) {
            self.unit = unit
        }
        deinit { print("Διαμέρισμα \(unit) απελευθερώθηκε") }
    }
    
    var john: Person?
    var unit4A: Apartment?
    
    john = Person(name: "John Appleseed")
    unit4A = Apartment(unit: "4A")
    
    john!.apartment = unit4A
    unit4A!.tenant = john // Εδώ θα δημιουργούνταν κυκλική αναφορά χωρίς `weak`
    
    // Οι αναφορές μηδενίζονται, τα αντικείμενα απελευθερώνονται
    john = nil
    unit4A = nil
    
  3. Unowned Reference (Ανεξάρτητη Αναφορά):

    • Δεν αυξάνει τον μετρητή αναφορών.
    • Επιτρέπει την απελευθέρωση του αντικειμένου αν δεν υπάρχουν ισχυρές αναφορές.
    • Ορίζεται με τη λέξη-κλειδί unowned.
    • Δεν είναι προαιρετική. Υποθέτει ότι το αντικείμενο πάντα θα υπάρχει όσο υπάρχει το αντικείμενο που το περιέχει.
    • Η πρόσβαση σε ένα απελευθερωμένο αντικείμενο μέσω unowned θα προκαλέσει σφάλμα χρόνου εκτέλεσης.
    • Χρησιμοποιείται για την αποφυγή κυκλικών αναφορών όταν ένα αντικείμενο πρέπει πάντα να υπάρχει όσο υπάρχει το άλλο.
    class Customer {
        let name: String
        var card: CreditCard?
        init(name: String) {
            self.name = name
        }
        deinit { print("\(name) απελευθερώθηκε") }
    }
    
    class CreditCard {
        let number: UInt64
        unowned let customer: Customer // Ανεξάρτητη αναφορά
        init(number: UInt64, customer: Customer) {
            self.number = number
            self.customer = customer
        }
        deinit { print("Κάρτα #\(number) απελευθερώθηκε") }
    }
    
    var john: Customer? = Customer(name: "John Appleseed")
    john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
    
    // Αν διαγράψουμε τον πελάτη, η κάρτα που αναφέρεται σε αυτόν με `unowned` θα γίνει μη έγκυρη, αλλά δεν θα δημιουργήσει κύκλο.
    john = nil // Και τα δύο αντικείμενα απελευθερώνονται
    

Η επιλογή μεταξύ weak και unowned εξαρτάται από τη φύση της σχέσης μεταξύ των αντικειμένων: χρησιμοποιήστε weak όταν ένα αντικείμενο μπορεί να υπάρχει χωρίς το άλλο (Person χωρίς Apartment), και unowned όταν ένα αντικείμενο πρέπει πάντα να υπάρχει όσο το άλλο υπάρχει (CreditCard ανήκει πάντα σε Customer).