Quelle est la différence entre les liens Wick et les liens Anound?
sobes.tech IA
Réponse de l'IA
La référence faible (weak) est une référence qui ne possède pas le contrôle du compteur de références de l'objet. Elle est utilisée pour éviter les cycles de références fortes, par exemple, entre un délégué et son propriétaire. Si l'objet pointé par la référence faible est désalloué, la référence faible devient automatiquement nil.
La référence non possédée (unowned) est également une référence qui ne possède pas le contrôle du compteur de références de l'objet. La différence avec weak est que unowned ne peut pas être optionnel (Optional) et doit toujours pointer vers un objet existant. Si l'objet pointé par la référence unowned est désalloué avant que la référence ne soit plus accessible, une tentative d'accès à cette référence entraînera une erreur d'exécution (erreur fatale). Elle est utilisée lorsque le cycle de vie de l'objet lié est garanti d'être plus long ou égal à celui de l'objet avec la référence unowned (par exemple, dans un cycle de références fortes où un des objets a un cycle de vie clairement défini).
Comparaison:
| Caractéristique | weak |
unowned |
|---|---|---|
| Non possédant | Oui | Oui |
| Incrémente le compteur | Non | Non |
Peut être nil |
Oui (se nullifie automatiquement) | Non (doit pointer vers un objet) |
| Sécurité | Plus sûre en cas de désallocation | Moins sûre (erreur fatale lors de l'accès à un objet désalloué) |
| Type | Doit être optionnel | Ne peut pas être optionnel (par défaut) |
| Utilisation | Prévenir les cycles de références fortes où l'objet peut cesser d'exister plus tôt | Prévenir les cycles de références fortes où l'objet garantit son existence |
Exemple d'utilisation de weak pour prévenir un cycle de références fortes:
class Person {
let name: String
weak var apartment: Apartment? // référence faible pour éviter le cycle de rétention
init(name: String) {
self.name = name
print("\(name) est en cours d'initialisation")
}
deinit {
print("\(name) est en cours de désinitialisation")
}
}
class Apartment {
let unit: String
var occupant: Person?
init(unit: String) {
self.unit = unit
print("Appartement \(unit) est en cours d'initialisation")
}
deinit {
print("Appartement \(unit) est en cours de désinitialisation")
}
}
Exemple d'utilisation de unowned dans le contexte de capturer self dans une fermeture:
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = {
[unowned self] in // self non possédant pour éviter le cycle de rétention avec la fermeture
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 cours de désinitialisation")
}
}