Middle
Qu'est-ce que unowned en Swift et comment l'utiliser?
sobes.tech IA
Réponse de l'IA
La référence non possédée (détention indirecte faible) en Swift est utilisée pour éviter les cycles de possession forte (cycles de rétention), lorsque deux objets se référencent mutuellement de manière forte, empêchant leur libération de la mémoire.
Caractéristiques de unowned :
- Garantit que l'objet référencé par la référence
unownedexiste toujours jusqu'au moment de l'utilisation de cette référence. - Si l'on tente d'accéder à la référence
unownedaprès que l'objet associé ait été libéré, une erreur d'exécution (crash à l'exécution) se produira. - Utilisé lorsque le cycle de vie de l'objet référant n'est pas plus long que celui de l'objet référencé. Autrement dit, la référence avec
unownedne rend pas l'objet plus fort.
Exemple d'utilisation dans une capture de clôture :
class Customer {
let name: String
var card: CreditCard?
init(name: String) {
self.name = name
}
deinit {
print("\(name) est en train d'être désinitialisé")
}
}
class CreditCard {
let number: UInt64
unowned let customer: Customer // Référence non possédée à Customer
init(number: UInt64, customer: Customer) {
self.number = number
self.customer = customer
}
deinit {
print("Carte #\(number) est en train d'être désinitialisée")
}
}
var john: Customer? // Customer optionnel pour permettre la libération
john = Customer(name: "John Appleseed")
john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!)
// L'assignation de nil à john entraînera la libération de Customer et Card,
// car il n'y a pas de cycle de possession forte
john = nil
Autre exemple - utilisation de unowned dans une liste de capture de clôture :
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = { [unowned self] in // Utilisation de 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) est en train d'être désinitialisé")
}
}
var paragraph: HTMLElement? // Élément HTML optionnel
paragraph = HTMLElement(name: "p", text: "bonjour le monde")
print(paragraph!.asHTML())
// La mise à nil libérera HTMLElement, car la clôture ne le retient pas fortement
paragraph = nil
Le choix entre unowned et weak dépend de si la référence peut être nil pendant la vie de l'objet. Si la référence ne peut jamais devenir nil avant la libération de l'objet, utilisez unowned. Si elle peut l'être, utilisez weak.