iOS学习笔记之Category
写在前面
Category是类别(也称为类目或范畴),使用Category,程序员可以为任何已有的类添加方法。使用类别可以对框架提供的类(无法获取源码,不能直接修改)进行扩展
Category的作用有以下几点:
将同一个类的实现分散到不同的文件或不同的框架中,方便代码的管理。
创建对私有方法的前向引用,当其他类中的方法没有实现时,访问其他类的私有方法时编译器会报错,这是使用类别,在类别中声明这些方法,编译器就不会报错
向对象添加非正式协议,创建一个NSObject的类别称为“创建一个非正式协议”,因为可以作为任何类的委托对象使用
使用列别案例
创建一个新项目,类型为基于Foundation的Command Line Tool,名称为VowelCounter。
创建一个新文件夹,类型为category,将其命名为VowelCounting,对应的类为NSString
在NSString+VowelCounting.h中为类别声明一个方法,该方法会被加入NSString类,代码如下:
#import <Foundation/Foundation.h>
@interface NSString (VowelCounting)
- (int)vowelCount;
@end
在NSString+VowelCounting.m中实现相应的方法,代码如下
#import "NSString+VowelCounting.h"
@implementation NSString (VowelCounting)
//统计有多少个原音字母
- (int)vowelCount
{
NSCharacterSet *charSet =
[NSCharacterSet characterSetWithCharactersInString:@"aeiouAEIOU"];
NSUInteger count = [self length];
int sum = 0;
for (int i = 0; i < count; i++) {
unichar c = [self characterAtIndex:i];
if ([charSet characterIsMember:c]) {
sum++;
}
}
return sum;
}
@end
在main.m中使用新创建的NSString方法,代码如下:
#import <Foundation/Foundation.h>
**#import "NSString+VowelCounting.h"**
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSString *string = @"This is a test for categroy!";
NSLog(@"%@ has %d vowels", string, [string vowelCount]);
}
return 0;
}
运行结果如下:
通过类别,我们向NSString类添加了一个新的方法vowelCount,并且能在后续的代码中使用vowelCount,只需要将vowelCount所在的头文件包含到相应的项目中即可,无需定义子类就可以扩展类的功能。
总结
尽管类别有很多有点,可以避免不必要的继承,但它同样存在一定的局限性
category无法为类添加新的实例变量
可能会出现名称冲突,如果类别和现有的方法重名,类别具有更高的优先级,这使得与新添加方法重名的那个方法永远也不会被调用。当然,也可以利用这点来覆盖就的方法。