Category
一、Category的使用
无论一个类设计的如何完美,都不可避免的会遇到没有预测到的需求,那怎么扩展现有的类呢?当然,继承是个不错的选择。但是Objective-C提供了一种特别的方式来扩展类,称为Category,可以动态的为现有的类添加新的行为。
例如,我们现在有一个Person类。
Person.h
1 @interface Person : NSObject 2 3 - (void) test; 4 5 @end
Person.m
1 #import "Person.h" 2 3 @implementation Person 4 5 - (void)test { 6 NSLog(@"调用了test方法"); 7 } 8 9 @end
现在要在不增加子类且不修改Person类的情况下增加一个test2方法。
在Xcode上新建文件,选择Objective-C category方式创建类:
Category填写分类名称,Category on选择Person类:
这样就会生成以“类名+分类名”命名的文件:
Person+Test.h
1 #import "Person.h" 2 3 //()代表是一个分类,()中的Test代表分类的名称 4 @interface Person (Test) { 5 //int age; //分类只能扩展方法,不能增加成员变量 6 } 7 8 - (void)test2; 9 10 @end
Person+Test.m
1 #import "Person+Test.h" 2 3 @implementation Person (Test) 4 5 - (void)test2 { 6 NSLog(@"调用了test2方法"); 7 } 8 9 @end
main.m
1 #import <Foundation/Foundation.h> 2 #import "Person+Test.h" //引入分类的头文件 3 4 int main(int argc, const char * argv[]) 5 { 6 7 @autoreleasepool { 8 9 Person *person = [[[Person alloc] init] autorelease]; 10 11 [person test]; //调用Person类的test方法 12 [person test2]; //调用分类的test2方法 13 14 } 15 return 0; 16 }
当然,分类也可以写在现有类文件中,不一定要分开文件写。
Person.h
1 #import <Foundation/Foundation.h> 2 3 @interface Person : NSObject 4 5 - (void)test; 6 7 @end 8 9 10 @interface Person (Test) 11 12 - (void)test2; 13 14 @end
Person.m
1 #import "Person.h" 2 3 @implementation Person 4 5 - (void)test { 6 NSLog(@"调用了test方法"); 7 } 8 9 @end 10 11 @implementation Person (Test) 12 13 - (void)test2 { 14 NSLog(@"调用了test2方法"); 15 } 16 17 @end
二、Category的使用场景
1、在某些情况下(例如需求变更),可能要为某个类添加方法时可以使用Category。
2、一个类中包含了许多不同的方法,而这些方法需要不同团队的成员实现时可以使用Category。
3、当你在使用基础类库中的类,可能要为这些类添加一些你需要的方法时可以使用Category。
三、Category的使用注意
1、Category可以访问原始类的成员变量,但不能添加成员变量,如果想添加成员变量,可以考虑通过继承创建子类。
2、Category可以重载原始类的方法,但不推荐这么做,这么做的后果是你再也不能访问原来的方法,如果确实要重载,正确的选择是创建子类。
3、和普通接口有所区别的是,在分类的实现文件中可以不必实现所有声明的方法,只要你不去调用它。