Categories are an Objective-C syntax for adding features to a class without subclassing it and without even having access to its code (its .m
file).
This comes in handy when you want to keep using a specific class (for example NSString
) but would like to add an extra feature.
We have seen categories before, when using the AFNetworking framework. UIImageView+AFNetworking
is a category on UIImage
that allows setting an image using a URL. It does this by adding methods to UIImage such as setImageWithURL:
and setImageWithURL:placeholderImage:
.
Categories have their own .h
and .m
files. These are usually named
. These can be easily created through the New File menu in Xcode.
Header | Source |
---|---|
#import <Foundation/Foundation.h> //-------------------------------------------------------------- //-------------------------------------------------------------- @interface NSString (Validation) @end |
#import "NSString+Validation.h" //-------------------------------------------------------------- //-------------------------------------------------------------- @implementation NSString (Validation) @end |
Categories can have their own methods and properties, but no instance variables. This means that properties must be implemented and cannot be synthesized.
Header | Source |
---|---|
#import <Foundation/Foundation.h> //-------------------------------------------------------------- //-------------------------------------------------------------- @interface NSString (Validation) - (BOOL)validateNotEmpty; - (BOOL)validateMinimumLength:(NSInteger)length; - (BOOL)validateMaximumLength:(NSInteger)length; @end |
#import "NSString+Validation.h" //-------------------------------------------------------------- //-------------------------------------------------------------- @implementation NSString (Validation) //-------------------------------------------------------------- - (BOOL)validateNotEmpty { return ([self length] != 0); } //-------------------------------------------------------------- - (BOOL)validateMinimumLength:(NSInteger)length { return ([self length] >= length); } //-------------------------------------------------------------- - (BOOL)validateMaximumLength:(NSInteger)length { return ([self length] <= length); } @end |
To use a category, we just need to import the header into the class where we need the additional functionality. This will make the extra methods available to use.
#import "ViewController.h" #import "NSString+Validation.h" //-------------------------------------------------------------- //-------------------------------------------------------------- @implementation ViewController //-------------------------------------------------------------- - (void)viewDidLoad { [super viewDidLoad]; NSString *myString = @"This is a string"; if ([myString validateNotEmpty]) { NSLog(@"1. Not empty!"); } else { NSLog(@"1. Empty!"); } if ([myString validateMinimumLength:6]) { NSLog(@"2. Min length OK"); } else { NSLog(@"2. Too short!"); } if ([myString validateMaximumLength:10]) { NSLog(@"3. Max length OK"); } else { NSLog(@"3. Too long!"); } } @end