分类中可以声明属性,因为声明属性其实就是声明设置方法和获取方法。但是分类中不可以合成属性,因为合成属性其实就是创建实例变量。
虽然不能在分类中创建实例变量,但是可以创建关联引用(associative reference)
。通过关联引用,你可以向任何对象中添加键-值(key-value)
数据
举个例子
有一个Father
类,这个Father
类可能会在其他程序中使用。有的时候address
这个字段有用,时候这个字段没用。一个比较好的办法就是使用分类为Father
这个类添加一个名为address
的属性,这样就可以避免不需要的时候开销。
首先看下Father
类
@interface Father : NSObject
@property (nonatomic,readwrite, copy) NSString *name;
@end
现在使用关联引用在分类中添加一个address
的属性
#import <objc/runtime.h>
@interface Father (Address)
@property (nonatomic, readwrite, copy) NSString *address;
@end
@implementation Father (Address)
static char addressKey;
- (NSString *)address {
return objc_getAssociatedObject(self, &addressKey);
}
- (void)setAddress:(NSString *)address {
objc_setAssociatedObject(self, &addressKey,
address,
OBJC_ASSOCIATION_COPY);
}
@end
- 可以看出,关联引用时基于
键(key)
的内存地址
的,而不是键
的值
。在addressKey
中存储的内容并不重要,但是它需要一个唯一的地址,所以通常使用一个未赋值的static char
作为键。
结束
关联引用有一个非常好的内存管理机制,可以根据传给的setAssociatedObject
的参数正确的处理复制、赋值、和保留语义。对象被收回的时候,关联引用会被正确的释放。
网友评论