Sobes.tech
Middle

Τι είδη συνδέσεων υπάρχουν στο Swift;

sobes.tech AI

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

Στη Swift υπάρχουν τρεις βασικοί τύποι αναφορών σε στιγμιότυπα κλάσεων:

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

    • Αυτός είναι ο προεπιλεγμένος τύπος αναφοράς.
    • Μία ισχυρή αναφορά αυξάνει τον μετρητή αναφορών του αντικειμένου.
    • Το αντικείμενο δεν θα απελευθερωθεί από τη μνήμη όσο υπάρχει τουλάχιστον μία ισχυρή αναφορά.
    • Ο κύριος λόγος για διαρροές μνήμης σε περίπτωση κυκλικών ισχυρών αναφορών (strong reference cycles).
    class Person {
        let name: String
        init(name: String) { self.name = name }
        deinit { print("\(name) απελευθερώνεται") }
    }
    
    var reference1: Person? = Person(name: "John")
    // reference1 τώρα είναι μια ισχυρή αναφορά, ο μετρητής αναφορών του Person αυξάνεται
    
  2. Αδύναμη Αναφορά (Weak Reference):

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

    • Δηλώνεται με τη λέξη-κλειδί unowned.
    • Όπως η αδύναμη αναφορά, δεν αυξάνει τον μετρητή αναφορών.
    • Χρησιμοποιείται επίσης για την αποφυγή strong reference cycles.
    • Σε αντίθεση με το weak, δεν είναι προαιρετική (Optional) και υποθέτει ότι το αντικείμενο στο οποίο αναφέρεται θα υπάρχει καθ' όλη τη διάρκεια ζωής της ανεξάρτητης αναφοράς.
    • Αν το αντικείμενο που αναφέρεται με unowned απελευθερωθεί πριν γίνει η πρόσβαση, θα προκύψει σφάλμα εκτέλεσης (runtime error).
    • Κατάλληλο για περιπτώσεις όπου ένα αντικείμενο πάντα υπάρχει όσο και ένα άλλο σχετικό αντικείμενο (π.χ. μια σχέση "γονέα-παιδιού", όπου ο γονέας κατέχει το παιδί, αλλά το παιδί δεν κατέχει τον γονέα με ισχυρό τρόπο).
    class Customer {
        let name: String
        var card: CreditCard?
        init(name: String) { self.name = name }
        deinit { print("\(name) απελευθερώνεται") }
    }
    
    class CreditCard {
        let number: Int
        unowned let customer: Customer // Ανεξάρτητη αναφορά
    
        init(number: Int, customer: Customer) {
            self.number = number
            self.customer = customer // Η ανάθεση της ανεξάρτητης αναφοράς είναι ασφαλής στο init
        }
        deinit { print("Κάρτα #\(number) απελευθερώνεται") }
    }
    
    var john: Customer? = Customer(name: "John Doe")
    john?.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
    
    // Διαγραφή της ισχυρής αναφοράς στον Customer
    john = nil
    // Έξοδος: "John Doe απελευθερώνεται", "Κάρτα #1234567890123456 απελευθερώνεται"
    // Η ανεξάρτητη αναφορά στον customer στην CreditCard ήταν έγκυρη όσο ο customer υπήρχε.
    // Αν η CreditCard ζούσε περισσότερο από τον Customer και προσπαθούσαμε να έχουμε πρόσβαση στον customer μέσω της ανεξάρτητης αναφοράς, θα προέκυπτε σφάλμα.
    

Βασική διαφορά μεταξύ weak και unowned:

  • weak: το αντικείμενο μπορεί να είναι nil. Χρησιμοποιήστε το όταν η διάρκεια ζωής των αντικειμένων δεν είναι αυστηρα συνδεδεμένη (ένα μπορεί να υπάρχει χωρίς το άλλο).
  • unowned: το αντικείμενο δεν μπορεί να είναι nil μετά την αρχικοποίηση. Χρησιμοποιήστε το όταν είστε βέβαιοι ότι το αναφερόμενο αντικείμενο θα υπάρχει τουλάχιστον μέχρι να υπάρχει το αντικείμενο που κάνει την αναφορά.