Qual è la differenza tra link Wick e link Anound?
sobes.tech AI
Risposta dell'AI
Il riferimento debole (weak) è un riferimento che non aumenta il contatore di riferimenti dell'oggetto. Viene utilizzato per prevenire cicli di riferimenti forti, ad esempio tra un delegato e il suo proprietario. Se l'oggetto a cui punta il riferimento debole viene deallocato, il riferimento debole diventa automaticamente nil.
Il riferimento non posseduto (unowned) è anch'esso un riferimento che non aumenta il contatore di riferimenti dell'oggetto. La differenza con weak è che unowned non può essere opzionale (Optional) e deve sempre puntare a un oggetto esistente. Se l'oggetto a cui punta il riferimento unowned viene deallocato prima che il riferimento smetta di esistere, l'accesso a tale riferimento causerà un errore di runtime (errore fatale). Viene usato quando il ciclo di vita dell'oggetto collegato è garantito essere più lungo o uguale a quello dell'oggetto con il riferimento unowned (ad esempio, in un ciclo di riferimenti forti in cui uno degli oggetti ha un ciclo di vita chiaramente definito).
Confronto:
| Caratteristica | weak |
unowned |
|---|---|---|
| Non possedente | Sì | Sì |
| Aumenta il contatore | No | No |
Può essere nil |
Sì (si azzera automaticamente) | No (deve puntare a un oggetto) |
| Sicurezza | Più sicura in caso di deallocazione | Meno sicura (errore fatale all'accesso a oggetto deallocato) |
| Tipo | Deve essere opzionale | Non può essere opzionale (per default) |
| Uso | Prevenire cicli di riferimenti forti, dove l'oggetto può cessare di esistere prima | Prevenire cicli di riferimenti forti, dove l'oggetto garantisce la propria esistenza |
Esempio di utilizzo di weak per prevenire un ciclo di riferimenti forti:
class Person {
let name: String
weak var apartment: Apartment? // riferimento debole per evitare ciclo di ritenzione
init(name: String) {
self.name = name
print("\(name) viene inizializzato")
}
deinit {
print("\(name) viene deinizializzato")
}
}
class Apartment {
let unit: String
var occupant: Person?
init(unit: String) {
self.unit = unit
print("Appartamento \(unit) viene inizializzato")
}
deinit {
print("Appartamento \(unit) viene deinizializzato")
}
}
Esempio di utilizzo di unowned nel contesto di cattura di self in una chiusura:
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = {
[unowned self] in // self non posseduto per evitare ciclo di ritenzione con la chiusura
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) viene deinizializzato")
}
}