Middle
Quali sono i tipi di riferimenti in Swift?
sobes.tech AI
Risposta dell'AI
In Swift, ci sono tre principali tipi di riferimenti:
-
**Riferimento Forte (Strong Reference):
- Aumenta il contatore di riferimenti dell'oggetto.
- Impedisce la deallocazione dell'oggetto finché esiste almeno un riferimento forte.
- È il tipo di riferimento predefinito in Swift.
- La causa principale di cicli di riferimenti forti.
-
**Riferimento Debole (Weak Reference):
- Non aumenta il contatore di riferimenti.
- Permette la deallocazione dell'oggetto se non ci sono più riferimenti forti.
- Viene dichiarato usando la parola chiave
weak. - È sempre opzionale (
Optional), poiché l'oggetto referenziato può diventarenil. - Viene usato per prevenire cicli di riferimenti forti, quando un'istanza può esistere indipendentemente dall'altra.
class Person { let name: String weak var apartment: Apartment? // Riferimento debole init(name: String) { self.name = name } deinit { print("\(name) deallocato") } } class Apartment { let unit: String var tenant: Person? // Riferimento forte normale init(unit: String) { self.unit = unit } deinit { print("Appartamento \(unit) deallocato") } } var john: Person? var unit4A: Apartment? john = Person(name: "John Appleseed") unit4A = Apartment(unit: "4A") john!.apartment = unit4A unit4A!.tenant = john // Qui si potrebbe creare un ciclo di riferimenti forti senza weak // Le referenze vengono azzerate, gli oggetti deallocati john = nil unit4A = nil -
**Riferimento Non Posseduto (Unowned Reference):
- Non aumenta il contatore di riferimenti.
- Permette la deallocazione dell'oggetto se non ci sono più riferimenti forti.
- Viene dichiarato usando la parola chiave
unowned. - Non è opzionale. Si presume che l'oggetto referenziato esisterà sempre finché esiste l'istanza che contiene il riferimento non posseduto.
- L'uso di un riferimento non posseduto su un oggetto già deallocato causerà un errore in fase di esecuzione (crash).
- Viene usato per prevenire cicli di riferimenti forti, quando un'istanza deve sempre esistere finché un'altra esiste, e non c'è possibilità che uno dei due diventi
nilindipendentemente dall'altro (ad esempio, in chiusure conself).
class Customer { let name: String var card: CreditCard? init(name: String) { self.name = name } deinit { print("\(name) deallocato") } } class CreditCard { let number: UInt64 unowned let customer: Customer // Riferimento non posseduto init(number: UInt64, customer: Customer) { self.number = number self.customer = customer } deinit { print("Carta #\(number) deallocata") } } var john: Customer? = Customer(name: "John Appleseed") john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!) // Se si annulla il cliente, la carta che fa riferimento a lui con unowned, // diventerà invalida, ma non causerà ciclo. john = nil // Entrambi gli oggetti vengono deallocati
La scelta tra weak e unowned dipende dalla natura della relazione tra gli oggetti: usa weak quando un oggetto può esistere senza l'altro (Person senza Apartment), e unowned quando un oggetto deve sempre esistere finché l'altro esiste (CreditCard appartiene sempre a Customer).