As an alternative to subclassing, Objective-C categories provide a means to add methods to a class. What’s intriguing, is that any methods that you add through a category become part of the class definition, so to speak. In other words, if you add a method to the NSString class, any instance, or subclass, of NSString will have access to that method.
Defining a category is identical to defining the interface for a class, with one small exception: you add a category name inside a set of parenthesis after the interface declaration. The format is shown below:
@interface ClassToAddMethodsTo (category)
...methods go here
@end
For example, below I’ve defined a category that adds a method to the NSString class. The methodreverseString adds the capability to all NSString objects to reverse the characters in the string.
//categories 可以为已经存在的类添加自己定义的方法,但是不能有成员变量
//比如为NSString 类添加一个自己定义的方法 reverseString
//需要自己创建一个 .m 和.h 文件 名字随意 这个例子中是 NSString+Reverse.h 和 NSString+Reverse.m
//NSString+Reverse.h 文件如下写
@interface NSString (reverse) //NSString 是要修改的类的名称 (reverse)是自己起的名,随意
-(NSString *) reverseString;
@end
As with the @interface declaration, the @implementation section changes only in that the category name is added to the definition. Below is the implementation of the interface defined above. Notice how in both cases I added (reverse) , which is the category name I assigned.
@implementation NSString (reverse)
-(NSString *) reverseString//NSString+Reverse.m 里面实现刚刚声明的方法
{
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
What follows is a short example to showing how one might use the above category.
#import <Foundation/Foundation.h>
#import "NSString+Reverse.h"
//引入这个头文件后,NSString就会多一个刚刚定义的函数
//貌似category 还可以减少函数,文章结尾是这么说的
//using categories – the example will show one approach for hiding methods within in a //class
//没有再细看了,貌似没有必要
int main (int argc, const char * argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *str = [NSString stringWithString:@"Fubar"];
NSString *rev;
NSLog(@"String: %@", str);
rev = [str reverseString];//此处调用
NSLog(@"Reversed: %@",rev);
[pool drain];
return 0;
}
The output of the above example is shown here:
//图片用不了
Categories can also be used to override methods the class inherits, again, providing an alternative to subclassing. You can always access the overridden method using super . I would assume from an internal (compiler/code generation) perspective, this could lead to less code/overhead as compared to creating a subclass solely to override a method (caveat: I have no proof that is true).
Dividing Source Code into Separate File
Although I haven’t given this a go, categories provide an interesting opportunity to disperse the implementation of a class across one or more files. The Objective-C Programming Guide lists several benefits of this including:
Opportunity to group together methods that perform similar tasks.
Configuring classes differently for various applications, yet maintaining one set of code.
Naming Conventions
The recommended naming convention for a category is “ClassToAddMethodsTo+CatgoryName” for instance, I used the following filenames for the interface and implementation of the above category code:
NSString+Reverse.h
NSString+Reverse.m
Caveats
You cannot add instance variables to a class through a category. Also, category names must be unique across an application.
Source Code
I’ve attached the Xcode project for the above example if you’d like to give it a try.
In the next post I’ll show another example of using categories – the example will show one approach for hiding methods within in a class, as Objective-C does not offer support for private methods.
原文地址 :http://macdevelopertips.com/objective-c/objective-c-categories.html