Ποια είναι η διαφορά μεταξύ των συνδέσμων Wick και των συνδέσμων Anound;
sobes.tech AI
Απάντηση από AI
Ο ασθενής αναφορά (weak) είναι μια αναφορά που δεν αυξάνει τον μετρητή αναφορών του αντικειμένου. Χρησιμοποιείται για την αποτροπή κύκλων ισχυρών αναφορών, για παράδειγμα, μεταξύ ενός διαμεσολαβητή και του ιδιοκτήτη του. Αν το αντικείμενο στο οποίο δείχνει η ασθενής αναφορά διαγραφεί, η ασθενής αναφορά γίνεται αυτόματα nil.
Η αναφορά χωρίς ιδιοκτησία (unowned) είναι επίσης μια αναφορά που δεν αυξάνει τον μετρητή αναφορών του αντικειμένου. Η διαφορά με το weak είναι ότι το unowned δεν μπορεί να είναι προαιρετικό (Optional) και πρέπει πάντα να δείχνει σε ένα υπάρχον αντικείμενο. Αν το αντικείμενο στο οποίο δείχνει η unowned αναφορά διαγραφεί πριν από την πρόσβαση σε αυτή, θα προκληθεί σφάλμα εκτέλεσης (fatal error). Χρησιμοποιείται εκεί όπου ο κύκλος ζωής του σχετιζόμενου αντικειμένου είναι εγγυημένο ότι είναι μεγαλύτερος ή ίσος με τον κύκλο ζωής του αντικειμένου με την unowned αναφορά (για παράδειγμα, σε κύκλο ισχυρών αναφορών όπου ένα από τα αντικείμενα έχει σαφώς ορισμένο κύκλο ζωής).
Σύγκριση:
| Χαρακτηριστικό | weak |
unowned |
|---|---|---|
| Μη ιδιοκτήτης | Ναι | Ναι |
| Αυξάνει το SC | Όχι | Όχι |
Μπορεί να είναι nil |
Ναι (αυτόματα μηδενίζεται) | Όχι (πρέπει πάντα να δείχνει σε αντικείμενο) |
| Ασφάλεια | Πιο ασφαλές σε περίπτωση διαγραφής | Λιγότερο ασφαλές (fatal σφάλμα κατά την πρόσβαση σε διαγραμμένο αντικείμενο) |
| Τύπος | Πρέπει να είναι προαιρετικό | Δεν μπορεί να είναι προαιρετικό (προεπιλογή) |
| Χρήση | Πρόληψη κύκλων ισχυρών αναφορών, όπου το αντικείμενο μπορεί να σταματήσει να υφίσταται νωρίτερα | Πρόληψη κύκλων ισχυρών αναφορών, όπου το αντικείμενο εγγυάται την ύπαρξή του |
Παράδειγμα χρήσης weak για την αποτροπή κύκλου ισχυρών αναφορών:
class Person {
let name: String
weak var apartment: Apartment? // ασθενής αναφορά για αποφυγή κύκλου
init(name: String) {
self.name = name
print("\(name) αρχικοποιείται")
}
deinit {
print("\(name) αφαιρείται")
}
}
class Apartment {
let unit: String
var occupant: Person?
init(unit: String) {
self.unit = unit
print("Διαμέρισμα \(unit) αρχικοποιείται")
}
deinit {
print("Διαμέρισμα \(unit) αφαιρείται")
}
}
Παράδειγμα χρήσης unowned στο πλαίσιο της καταγραφής του self σε κλείσιμο:
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = {
[unowned self] in // unowned self για αποφυγή κύκλου
if let text = self.text {
return "<\(self.name)>\(text)</\(self.name)>"
} else {
return "<\(self.name) />"
}
}
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
deinit {
print("\(name) αφαιρείται")
}
}