Intern
Cos'è un garbage collector?
sobes.tech AI
Risposta dell'AI
Su iOS, non esiste un tradizionale raccoglitore di spazzatura. Al suo posto, viene utilizzato il meccanismo di Riferimento Automatico (ARC).
- Meccanismo automatico: ARC conta automaticamente i riferimenti forti agli oggetti.
- Rilascio della memoria: Quando il conteggio dei riferimenti forti a un oggetto raggiunge zero, ARC libera la memoria allocata.
- Prevenzione delle perdite: L'uso corretto di riferimenti forti, deboli e non posseduti (unowned) permette di prevenire perdite di memoria e cicli di riferimenti.
Tipi di riferimenti in ARC:
- Forti (strong): Aumenta il contatore di riferimenti. È il valore predefinito.
- Deboli (weak): Non aumenta il contatore di riferimenti. Diventa automaticamente
nilquando l'oggetto viene deallocato. Usato per prevenire cicli di riferimenti forti. Viene dichiarato come un tipo opzionale. - Non posseduti (unowned): Non aumenta il contatore di riferimenti. È garantito che l'oggetto a cui si riferisce esista durante tutto il ciclo di vita del riferimento non posseduto. Non è opzionale. Usato quando due oggetti hanno una relazione forte reciproca, ma uno di essi ha un ciclo di vita più breve.
Vantaggi di ARC:
- Prevedibilità: La liberazione della memoria avviene in modo deterministico, non appena l'oggetto non viene più utilizzato.
- Prestazioni: Non ci sono costi aggiuntivi per il garbage collector in background, che può causare pause.
- Semplicità: Lo sviluppatore non deve gestire manualmente la memoria nella maggior parte dei casi, ma deve comprendere i principi del conteggio dei riferimenti per prevenire perdite.
Esempio di ciclo di riferimenti forti:
class Person {
let name: String
var apartment: Apartment? // riferimento forte ad Apartment
init(name: String) { self.name = name }
deinit { print("\(name) viene deallocato") }
}
class Apartment {
let unit: String
weak var tenant: Person? // riferimento debole a Person per prevenire ciclo
init(unit: String) { self.unit = unit }
deinit { print("Appartamento \(unit) viene deallocato") }
}
var john: Person?
var unit4A: Apartment?
john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john // L'uso di weak qui è critico
john = nil
unit4A = nil
// Senza tenant weak: Sia john che unit4A non verrebbero deallocati.
// Con tenant weak: Sia john che unit4A vengono deallocati correttamente.