Le category permettono di aggiungere un metodo a una classe esistente senza estenderla. È importante quindi distinguere questa tecnica dal subclassing.
Infatti, mentre col subclassing stiamo creando una nuova classe, utilizzando la category aggiungiamo un metodo alla classe originale.
Facciamo un esempio. Abbiamo già utilizzato delle stringhe in precedenza. Ogni volta che abbiamo scritto @"Hello world"
, infatti, non abbiamo fatto altro che definire un’istanza di NSString.
Immaginiamo di voler aggiungere a NSString un metodo che ci dica se quella stringa è un palindroma.
Dal nostro progetto, selezioniamo File > New > File....
Scegliamo Objective-C File e poi Next.
Indichiamo il nome della nostra Category (ovvero Palindrome), poi indichiamo a Xcode che stiamo effettivamente creando una Category e infine indichiamo la classe a cui vogliamo aggiungere funzionalità (NSString).
Premiamo Next e poi Create.
Se osserviamo il Project navigator sulla sinistra, vedremo che Xcode ha creato 2 file.
Come abbiamo fatto in fase di definizione di una classe, dobbiamo dichiarare il nuovo metodo nel file NSString+Palindrome.h e poi implementarlo in NSString+Palindrome.m. La differenza sarà che questa volta il metodo che definiremo sarà disponibile a tutte le istanza di NSString.
Iniziamo aprendo NSString+Palindrome.h e modifichiamolo come mostrato di seguito:
#import <Foundation/Foundation.h>
@interface NSString (Palindrome)
- (BOOL)isPalindrome;
@end
Poi passiamo a NSString+Palindrome.h e modifichiamolo come segue:
#import "NSString+Palindrome.h"
@implementation NSString (Palindrome)
- (BOOL)isPalindrome {
NSInteger length = self.length;
NSInteger halfLength = (length / 2);
for (int i = 0; i < halfLength; i++) {
if ([self characterAtIndex:i] != [self characterAtIndex:length - i - 1]) {
return NO;
}
}
return YES;
}
@end
Ora torniamo al nostro file main.m e testiamo la nuova funzionalità che abbiamo aggiunto alla classe NSString.
@import Foundation;
#import "Car.h"
#import "Bicycle.h"
#import "NSString+Palindrome.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString * word = @"radar";
if ([word isPalindrome]) {
NSLog(@"%@ is palindrome", word);
} else {
NSLog(@"%@ is NOT palindrome", word);
}
}
return 0;
}
Come vedete, una volta aggiunto l’import #import "NSString+Palindrome.h"
possiamo utilizzare il nuovo metodo isPalindrome
aggiunto alla classe originale NSString.
Premiamo infine CMD + R sulla tastiera per provare il risultato. Possiamo sostituire @"radar" con altre stringhe per effettuare altri test.