Middle
Τι είναι το unowned στη γλώσσα Swift και πώς χρησιμοποιείται;
sobes.tech AI
Απάντηση από AI
Η μη κατέχουσα αναφορά (αδύναμη έμμεση ιδιοκτησία) στο Swift χρησιμοποιείται για την αποφυγή κύκλων ισχυρής ιδιοκτησίας (retain cycles), όταν δύο αντικείμενα αναφέρονται το ένα στο άλλο με ισχυρό τρόπο, εμποδίζοντας την απελευθέρωσή τους από τη μνήμη.
Χαρακτηριστικά του unowned:
- Διασφαλίζει ότι το αντικείμενο στο οποίο αναφέρεται η
unownedαναφορά υπάρχει πάντα μέχρι τη στιγμή που χρησιμοποιείται. - Αν προσπαθήσετε να αποκτήσετε πρόσβαση στην
unownedαναφορά μετά την απελευθέρωση του σχετικού αντικειμένου, θα προκληθεί σφάλμα κατά την εκτέλεση (runtime crash). - Χρησιμοποιείται όταν ο κύκλος ζωής του αντικειμένου που αναφέρεται δεν είναι μεγαλύτερος από αυτό του αντικειμένου που αναφέρεται. Με άλλα λόγια, η
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 // Μη κατέχουσα αναφορά σε Customer
init(number: UInt64, customer: Customer) {
self.number = number
self.customer = customer
}
deinit {
print("Κάρτα #\(number) απελευθερώνεται")
}
}
var john: Customer? // Προαιρετικός Customer για απελευθέρωση
john = Customer(name: "John Appleseed")
john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
// Ανάθεση nil στον john θα οδηγήσει στην απελευθέρωση του Customer και της Card,
// καθώς δεν υπάρχει κύκλος ισχυρής ιδιοκτησίας
john = nil
Άλλο παράδειγμα - χρήση του unowned σε λίστα σύλληψης κλεισίματος:
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) απελευθερώνεται")
}
}
var paragraph: HTMLElement? // Προαιρετικό στοιχείο HTML
paragraph = HTMLElement(name: "p", text: "γεια σου κόσμε")
print(paragraph!.asHTML())
// Ανάθεση nil θα απελευθερώσει το HTMLElement, καθώς η κλεισίματος δεν το κρατάει ισχυρά
paragraph = nil
Η επιλογή μεταξύ unowned και weak εξαρτάται από το αν η αναφορά μπορεί να γίνει nil κατά τη διάρκεια ζωής του αντικειμένου. Αν η αναφορά ποτέ δεν μπορεί να γίνει nil πριν από την απελευθέρωση του αντικειμένου, χρησιμοποιήστε unowned. Αν μπορεί, χρησιμοποιήστε weak.