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