给已有类添加方法使用类别(Category)就可以了, 步骤也很简单, Xcode已集成好了创建类别的框架.
那么怎么给已有类拓展一个属性, 甚至更多呢? 网上也有不少方法, 我在此分享一种使用runtime机制来实现此功能.
以NSString为例:
给NSString类添加两种类型的属性, 字符串类型的tag值strFlag, 以及int型的tag值intTag.
定义这个两个属性的set和get方法:
<span style="font-size:18px;">@interface NSString (Ass)
// 对象属性的set和get
- (void)setStrFlag:(NSString *)strFlag;
- (NSString *)strFlag;
// 非对象属性的set和get
- (void)setIntFlag:(int)intFlag;
- (int)intFlag;
@end</span>
实现这四个方法:
需导入runtime头文件:
#import <objc/runtime.h>
@implementation NSString (Ass)
static int _intFlag;
static NSString *_strFlag;
- (void)setStrFlag:(NSString *)flag {
// void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
objc_setAssociatedObject(self, &_strFlag, flag, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSString *)strFlag {
// id objc_getAssociatedObject(id object, const void *key)
return objc_getAssociatedObject(self, &_strFlag);
}
- (void)setIntFlag:(int)intFlag {
NSNumber *t = @(intFlag);
// void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
objc_setAssociatedObject(self, &_intFlag, t, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (int)intFlag {
// id objc_getAssociatedObject(id object, const void *key)
NSNumber *t = objc_getAssociatedObject(self, &_intFlag);
return (int)[t integerValue];
}
@end
使用规则和类别差不多, 一个是拓展了方法, 一个是拓展了属性而已:
NSString *str = @"Macro "; // 定义一个系统的NSString对象
str.strFlag = @"abc"; // 给字符串tag赋值
str.intFlag = 456; // 给int型tag赋值
NSLog(@"%@:%@-%d", str, str.strFlag, str.intFlag); // 使用拓展的属性
工程源码