类别,有些程序员又称之为分类。
类别是一种为现有的类添加新方法的方式,尤其是为系统的做扩展的时候,不用继承系统类,可以直接为类添加新的方法。也可以覆盖系统类的方法。
如:
@interface NSObject (MyCategory)
- (void)myMethod;
@end
这样我们就给NSObject 添加了一个方法 myMethod()。
注意,一般情况下,我们只用分类为现有类添加方法,而很少为现有类添加属性。
假设我们有一个Person 类
person.h
1 @interface Person : NSObject 2 @property(nonatomic,strong) NSString *name; 3 @property(nonatomic,assign)NSUIteger age; 4 -(void)job; 5 @end
person.m
1 #import "Person.h" 2 3 @implementation Person 4 -(void)job{ 5 NSLog(@"工作不加班,工作不加班"); 6 } 7 @end
现在我们为Person创建一个分类
Person+Weapon.h
1 #import "Person.h" 2 @interface Person (Weapon) 3 -(void)fire; 4 @end
Person+Weapon.m
1 #import "Person+Weapon.h" 2 3 @implementation Person (Weapon) 4 -(void)fire{ 5 NSLog(@"%@具备了开火的能力 ",self.name); 6 } 7 @end
main.m
1 #import <Foundation/Foundation.h> 2 #import "Person.h" 3 #import "Person+Weapon.h" 4 int main(int argc, const char * argv[]) 5 { 6 7 @autoreleasepool { 8 Person *person = [[Person alloc]init]; 9 person.name = @"小王"; 10 [person job]; 11 [person fire]; 12 } 13 return 0; 14 }
运行结果:
2015-07-25 13:35:06.111 分类[1065:68110] 工作不加班,工作不加班
2015-07-25 13:35:06.112 分类[1065:68110] 小王具备了开火的能力!
通过以上例子可以看出,本来类Person 只有一个job工作的能力,我们通过分类weapon,为Person添加了新的方法开火。
有时我们也需要运用分类给,可以使用runtime机制为类别添加属性。
方法如下:
1、在定义类别之前引如runtime
#import<obj/runtime.h>
2、定义、实现类别
Person+Weapon.h
1 #import <objc/runtime.h> 2 #import "Person.h" 3 @interface Person (Weapon) 4 @property (nonatomic,retain) NSString *address;//分类中添加的新属性address 5 -(void)fire; 6 @end
Person+Weapon.m
1 #import "Person+Weapon.h" 2 static const char *addressKey = "上海浦东"; 3 @implementation Person (Weapon) 4 -(void)fire{ 5 NSLog(@"%@具备了开火的能力!",self.name); 6 } 7 //getter 8 - (NSString *)address { 9 return (NSString *)objc_getAssociatedObject(self, addressKey); 10 } 11 //setter 12 - (void)setAddress:(NSString *)newAddressKey { 13 objc_setAssociatedObject(self, addressKey, newAddressKey, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 14 } 15 @end
main.m
1 #import <Foundation/Foundation.h> 2 #import "Person.h" 3 #import "Person+Weapon.h" 4 int main(int argc, const char * argv[]) 5 { 6 7 @autoreleasepool { 8 TRPerson *person = [[Person alloc]init]; 9 person.name = @"小王"; 10 person.address = @"北京天安门"; 11 NSLog(@"%@搬家到%@",person.name,person.address); 12 [person job]; 13 [person fire]; 14 } 15 return 0; 16 }
运行结果:
2015-07-25 14:01:09.672 分类[1097:76981] 小王搬家到北京天安门
2015-07-25 14:01:09.673 分类[1097:76981] 工作不加班,工作不加班
2015-07-25 14:01:09.673 分类[1097:76981] 小王具备了开火的能力!
类别的作用:
(1)将类的实现分散到多个不同文件或多个不同框架中。
(2)创建对私有方法的前向引用。(个人感觉最主要的作用就是欺骗编译器,如果编译器找不到相关的函数,我们可以用分类声明一个,不必实现而让编译器通过编译)
(3)向对象添加非正式协议。(非正式协议是NSObject的一个类别,他可以列出对象能够响应的方法)