Cos'è unowned?
sobes.tech AI
Risposta dell'AI
unowned — è una parola chiave in Swift per dichiarare un riferimento non opzionale. Viene usato quando due oggetti hanno una relazione forte e i loro cicli di vita dipendono l'uno dall'altro, ma vogliamo evitare riferimenti ciclici che potrebbero impedire la liberazione della memoria.
Proprietà principali e differenze con weak:
- Non opzionale: Il riferimento
unownednon sarànildurante tutta la vita dell'oggetto a cui si riferisce. - Relazione forte: Usato quando un oggetto possiede un altro e entrambi esistono sempre insieme.
- Durante la liberazione: Se l'oggetto a cui si riferisce il riferimento
unownedviene liberato dalla memoria prima che il riferimento venga usato, ciò provocherà un errore in runtime. È necessario assicurarsi che l'oggetto referenziato esista più a lungo del riferimento stesso. - Applicazione: Spesso usato per i delegati, quando il delegato esiste sempre più a lungo dell'oggetto che lo chiama, o negli closures per evitare riferimenti ciclici a
self, quando il closure non cattura un riferimento forte aself.
Esempio di utilizzo in un closure:
// swift
class MyClass {
var name: String
var closure: (() -> Void)?
init(name: String) {
self.name = name
}
func setupClosure() {
closure = { [unowned self] in // Uso di unowned self
print("Il mio nome è \(self.name)")
}
}
deinit {
print("\(name) deallocato")
}
}
Esempio di utilizzo per un delegato (anche se weak è più comunemente usato per i delegati, unowned è comunque possibile se il delegato garantisce di vivere più a lungo):
// swift
protocol MyDelegate: AnyObject { // AnyObject richiede un tipo di riferimento
func doSomething()
}
class DataSource {
unowned var delegate: MyDelegate // riferimento `unowned` al delegato
init(delegate: MyDelegate) {
self.delegate = delegate
}
func performAction() {
delegate.doSomething()
}
deinit {
print("DataSource deallocato")
}
}
class MyController: MyDelegate {
var dataSource: DataSource?
override init() {
super.init()
dataSource = DataSource(delegate: self)
}
func doSomething() {
print("Metodo del delegato chiamato")
}
deinit {
print("MyController deallocato")
}
}
La scelta tra weak e unowned dipende dal fatto che la referenza sia opzionale e se l'oggetto referenziato esiste garantito fino alla fine della vita della referenza. Se c'è la possibilità che l'oggetto venga liberato prima di usare la referenza, si dovrebbe usare weak. Se la garanzia di esistenza è assicurata e la referenza non deve essere opzionale, si può usare unowned.