Categories
Syntax#
-
@interface ClassName (categoryName) // ClassName is the class to be extended
-
// Method and property declarations
-
@end
Remarks#
To avoid method name clashes, it is recommended to use prefixes (like xyz_
in the example). If methods with the same name exist, it is undefined which one will be used in the runtime.
Simple Category
Interface and implementation of a simple category on NSArray, named Filter, with a single method that filters numbers.
It is good practice to add a prefix (PF
) to the method to ensure we don’t overwrite any future NSArray
methods.
@interface NSArray (PFFilter)
- (NSArray *)pf_filterSmaller:(double)number;
@end
@implementation NSArray (PFFilter)
- (NSArray *)pf_filterSmaller:(double)number
{
NSMutableArray *result = [NSMutableArray array];
for (id val in self)
{
if ([val isKindOfClass:[NSNumber class] && [val doubleValue] >= number)
{
[result addObject:val];
}
}
return [result copy];
}
@end
Declaring a class method
Header file UIColor+XYZPalette.h
:
@interface UIColor (XYZPalette)
+(UIColor *)xyz_indigoColor;
@end
and implementation UIColor+XYZPalette.m
:
@implementation UIColor (XYZPalette)
+(UIColor *)xyz_indigoColor
{
return [UIColor colorWithRed:75/255.0f green:0/255.0f blue:130/255.0f alpha:1.0f];
}
@end
Adding a property with a category
Properties can be added with categories using associated objects, a feature of the Objective-C runtime.
Note that the property declaration of retain, nonatomic
matches the last argument to objc_setAssociatedObject
. See Attach object to another existing object for explanations.
#import <objc/runtime.h>
@interface UIViewController (ScreenName)
@property (retain, nonatomic) NSString *screenName;
@end
@implementation UIViewController (ScreenName)
@dynamic screenName;
- (NSString *)screenName {
return objc_getAssociatedObject(self, @selector(screenName));
}
- (void)setScreenName:(NSString *)screenName {
objc_setAssociatedObject(self, @selector(screenName), screenName, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
Conforming to protocol
You can add protocols to standard classes to extends their functionality:
@protocol EncodableToString <NSObject>
- (NSString *)toString;
@end
@interface NSDictionary (XYZExtended) <EncodableToString>
@end
@implementation NSDictionary (XYZExtended)
- (NSString *)toString {
return self.description;
}
@end
where XYZ
your project’s prefix
Create a Category on XCode
Categories provide the ability to add some extra functionality to an object without subclassing or changing the actual object.
For example we want to set some custom fonts.
Let’s create a category that add functionality to UIFont
class. Open your XCode project, click on File
-> New
-> File
and choose Objective-C file
, click Next enter your category name say “CustomFont” choose file type as Category and Class as UIFont then Click “Next” followed by “Create.”
Declare the Category Method :-
Click “UIFont+CustomFonts.h” to view the new category’s header file. Add the following code to the interface to declare the method.
@interface UIFont (CustomFonts)
+(UIFont *)productSansRegularFontWithSize:(CGFloat)size;
@end
Now Implement the Category Method:-
Click “UIFont+CustomFonts.m” to view the category’s implementation file. Add the following code to create a method that will set ProductSansRegular Font.
+(UIFont *)productSansRegularFontWithSize:(CGFloat)size{
return [UIFont fontWithName:@"ProductSans-Regular" size:size];
}
Import your category
#import "UIFont+CustomFonts.h"
Now set the Label font
[self.label setFont:[UIFont productSansRegularFontWithSize:16.0]];