Property Wrappers è un meccanismo che consente di incapsulare la logica di gestione delle proprietà (ad esempio, validazione, cambiamenti o memorizzazione in modo specifico) e di riutilizzarla per varie proprietà tramite annotazioni nel codice. Aiutano a eliminare il codice ripetitivo e migliorano la leggibilità.
Un Property Wrapper è una struttura, classe o enum che implementa il protocollo property wrapper tramite l'annotazione @propertyWrapper e la proprietà obbligatoria wrappedValue.
Limitazioni e sfumature:
Esempio: Scriviamo un property wrapper per limitare automaticamente l'intervallo di valore (Clamped).
@propertyWrapper struct Clamped<Value: Comparable> { var value: Value let range: ClosedRange<Value> var wrappedValue: Value { get { value } set { value = min(max(newValue, range.lowerBound), range.upperBound) } } init(wrappedValue initialValue: Value, _ range: ClosedRange<Value>) { self.range = range self.value = min(max(initialValue, range.lowerBound), range.upperBound) } } struct Person { @Clamped(0...120) var age: Int = 25 } var p = Person() p.age = 200 // Ora p.age = 120 p.age = -10 // Ora p.age = 0
Qual è il modo per accedere all'oggetto property wrapper originale al di fuori della struttura/classe in cui è stato applicato?
Risposta: Attraverso il nome della proprietà con un underscore (_). Ad esempio, se la proprietà si chiama age, l'oggetto property wrapper può essere ottenuto come _age:
var p = Person() let wrapper = p._age // questo è il tipo Clamped<Int>
Storia
In un progetto per la memorizzazione di UserDefaults è stato implementato un property wrapper personalizzato che lavorava con tipi primitivi. Quando veniva utilizzato per tipi di riferimento (class), si verificava una fuga di memoria inattesa: il property wrapper manteneva un strong reference all'oggetto, causando un ciclo forte e una perdita di dati. L'errore è stato corretto passando a weak/unowned reference all'interno del wrapper.
Storia
In un progetto si è tentato di applicare un property wrapper a proprietà calcolate, ma il compilatore ha restituito un errore: il property wrapper può essere utilizzato solo con stored property. Questo fatto è stato trascurato, causando un ritardo nello sviluppo del modulo di 2 giorni.
Storia
Durante la creazione della struttura di wrapping, è stata dimenticata l'implementazione della corretta sintassi di inizializzazione tramite init(wrappedValue:...). Di conseguenza, non era possibile impostare valori predefiniti tramite il property wrapper, il che è emerso solo dopo l'integrazione del wrapper in un gran numero di modelli. È stato necessario rivedere l'architettura.