今天由于要看ObjC的代码,学点基本知识,水平很有限!
published by john at 5:21 am under iphone, Objective-C
As an alternative to subclassing, Objective-C categories provide a means to add method to a class.
Objective-C categories提供一个可选的把方法加入到类的方式对于子集。
What's intriguing, is that any methods that you add through a category become part of the class definition, so to speak.
引起兴趣的是,通过category你加入的方法会成为类定义中的一部分,就这样说吧。
In other words, if you add a method to the NSString class, any instance, or subclass, of NSString will have access to that method.
换句话说,如果你加个方法到类NSString,NSString的任何实例或者子类肯定有访问这个方法的权利。
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.
定义category是与为类定义interface相同的,一点变化的是:在interface定义后接上一对插入了category名字的圆括号。
the format is shown below:
@interface ClassToAddMethodsTo (category)
...methods
@end
For example, below I've defined a category that adds a method to the NSString class.
The method reverseString adds the capability to all NSString objects to reverse the characters in the string.
方法reverseString对所有NSString的对象增加字符产反向字符的能力。
@interface NSString (reverse)
-(NSString)reverseString;
@end
As with the @interface declaration, the @implementation section changes only in that the category names is added to the definition.
与@interface段的申明一样,@implementation段的改变仅仅是category的名字加入到定义里去了。
Below is the implementation of the interface defined above. Notice how in both cases I added (reverse), which is the category name I assigned.
@implenmentation NSString (reverse)
-(NSString *) reverseString
{
NSMutableString *reversedStr;
int len = [self length];
// auto released string
reversedStr = [NSMutableString stringWithCapacity:len];
// probably woefully ineffioient...
while (len > 0)
{
[reversedStr appendString:[NSString stringWithFormat:@"%c", [self characterAtIndex:--len]]];
}
return reversedStr;
}
@end
What follows is a short example to showing how to one might use the above category.
接下来的例子就是展示怎么用上面的category的,大家要注意了。
#import <Foundation/Foundation.h>
#import <NSString+Reverse.h>
int main(int argc, const char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *str = [NSString stringWithString:@"Fubar"];
NLog(@"string: %@", str");
rev = [str reverseString];
NSLog(@"reversed: %@", rev);
[pool drain];
return 0;
}
The output of the above example is shown here:
结果大家去试下就知道,我就不打了。
Overriding Methods
Categories can also be used to override methods the class inherits, again, providing an alternaive to subclassing.
categories常常用来为子类在类的继承上重写方法提供又一种可选的方法。
You can always access the overridden method using super.
你总用关键字super去访问重写的方法。
I would assume from an internal (compiler/code generation) persperctive, this could lead to less code/overhead as compared to creating a subclass solely to override a method (caveat: I have to 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 Guid lists several benefits of the including:
- Opportunity to group together methods that perform similar tasks
- Confiuring classes differently for various applications, yet maintaining one set of code.
- 为各种应用程序配置不同的类,而且还能使这一代码集维持联系。
Naming Conventions 名称转换,要注意哦!
The recommended naming convention fo ra 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 throught a category. Also, category names must be unique across an application.
其实也没有什么,就是你不能在category加入变量,还有就是应用范围内你的名字保持唯一。OK
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 shwo 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. 你可以用category来隐藏方法,做到private,ObjC是没有提供private的哦!