Middle
Τι είδη συνδέσεων υπάρχουν στο Swift;
sobes.tech AI
Απάντηση από AI
Στη Swift υπάρχουν τρεις βασικοί τύποι αναφορών σε στιγμιότυπα κλάσεων:
-
Ισχυρή Αναφορά (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 αυξάνεται -
Αδύναμη Αναφορά (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) - Δηλώνεται με τη λέξη-κλειδί
-
Ανεξάρτητη Αναφορά (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μετά την αρχικοποίηση. Χρησιμοποιήστε το όταν είστε βέβαιοι ότι το αναφερόμενο αντικείμενο θα υπάρχει τουλάχιστον μέχρι να υπάρχει το αντικείμενο που κάνει την αναφορά.