Chi ha avuto modo di utilizzare Objective-C si è sicuramente imbattuto nelle Categories, che permettono di aggiungere metodi (ed estendere in generale) a classi esistenti senza creare nuovi tipi (o sotto tipi). Anche Swift permette di usare la stessa tecnica attraverso le Extensions.
A differenza delle Categories le Extensions non hanno un nome come si può vedere negli esempi seguenti.
Le Extensions in Swift permettono di:
- Aggiungere computed instance properties e computed type properties
- Definire instance methods e type methods
- Definire subscripts
- Definire nuovi inizializzatori / costruttori
- Definire e usare nuovi nested types
- Rendere un tipo esistente conforme a un protocollo
Un esempio di extension e suo utilizzo:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
extension Int { var doppio: Int { return self * 2 } func calcolaQuadrato() -> Int { return self * self } } var mioInt = 3 print(mioInt.calcolaQuadrato()) // 9 print(mioInt.doppio) // 6 |
Nell’esempio è stata creata una extension per il tipo Int aggiungendo un metodo per calcolare il quadrato e una computed property per calcolare il doppio del valore.
All’interno di una extension è anche possibile modificare il tipo stesso. Se all’interno di un metodo viene modificato il tipo, deve essere utilizzata la keyword mutating:
1 2 3 4 5 6 7 |
extension Int { mutating func quadrato() { self = self * self } } |
Le extensions possono inoltre essere usate per rendere un tipo o classe conforme a un protocollo:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
protocol TestProtocol { func protocolFunction() } extension Int: TestProtocol { func protocolFunction() { print("fa qualcosa") } } |
- Swift Extensions: (Documentazione Apple)
Aggiungere Stored Properties alle Extensions
Come per le Categories in Objective-C anche le Extensions di Swift non supportano nativamente le stored properties. Ho dedicato un post a come aggiungere stored properties alle Categories in Objective-C e il meccanismo per poterlo fare in Swift è il medesimo: associated objects messo a disposizione dal runtime di Objective-C e ovviamente importabile e utilizzabile anche in Swift.
1 2 3 4 5 6 7 8 |
func objc_getAssociatedObject(object: AnyObject!, key: UnsafePointer<Void> ) -> AnyObject! func objc_setAssociatedObject(object: AnyObject!, key: UnsafePointer<Void>, value: AnyObject!, policy: objc_AssociationPolicy) |
Per approfondimenti e il mapping degli argomenti si veda il post relativo all’uso di associated objects in Objective-C e i seguenti link:
- objc_getAssociatedObject: Documentazione (Apple)
- objc_setAssociatedObject: Documentazione (Apple)