Thursday, December 17, 2009

Using Objective-C Categories: The safe way


A Objective-C developer can add methods to an existing class by using categories. Let's assume you ever wanted NSString to have a -reverse method that returns the receiving string in reverse order. "Cocoa" would become "aocoC". So you extend NSString by writing a category that implements the reverse method.

Interface:

@interface NSString (reverse)
-(NSString *) reverse;
@end

Implementation:

@implementation NSString (reverse)

-(NSString *) reverse
{
  NSMutableString *reversedStr;
  int len = [self length];

  // Auto released string
  reversedStr = [NSMutableString stringWithCapacity:len];     

  // Probably woefully inefficient...
  while (len > 0)
    [reversedStr appendString:
         [NSString stringWithFormat:@"%C", [self characterAtIndex:--len]]];   

  return reversedStr;
}

@end


The actual code has no problem. The problem is the name of the method added by this category. What happens if you use a third party framework that also adds a reverse method to NSString? Well, the behavior is undefined. To solve this problem I suggest that you simply prefix methods you add by using categories with the same prefix you use to indicate "your" classes. To give an example: I prefix my classes with CMK which means that I prefix methods that I add by using a category with cmk_. In the example given above this means that reverse has to be renamed to cmk_reverse. This technique is also used by Google and Jonathan Rentzsch (in his method swizzle code).

In general you should avoid adding too many categories. Use them wisely.

No comments:

Post a Comment