介绍
使用Category可以很方便地为现有的类增加方法,但却无法直接增加实例变量.有时候我们需要在现有的类存放一些额外的信息,通常的做法是继承一个子类,然后定义新增加的属性,然而如果我们为每个需要的类都添加一个类显得太麻烦了,objc提供了一个关联属性的特性,可以给一个对象关联一个属性
要关联的对象的键值,一般设置成静态的,用于获取关联对象的值要关联的对象的值,从接口中可以看到接收的id类型,所以能关联任何对象关联时采用的协议,有assign,retain,copy等协议,具体可以参考官方文档
//设置关联属性 objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
//获取关联属性 id result = objc_getAssociatedObject(id object, const void *key)
//删除所有附加属性 objc_removeAssociatedObjects(id object)
关联属性的附加相当于NSDictionary,通过键值对存储,但是有一点跟NSDictionary不一样的是,设置关联对象所用的键(key)是不透明指针(opaque pointer),NSDictionary判断两个Key的isEqual方法判断是否相等,而关联对象只判断两个key的地址是否相等,而不会比较对象具体的值,所以通常我们在定义关联对象的key的时候使用静态全局变量作为键,这样可以保证地址一致
使用前
1.#import<objc/runtime>
2.推荐几种key值写法
(1)声明 static char kAssociatedObjectKey; ,使用 &kAssociatedObjectKey 作为 key 值;
(2)声明 static void *kAssociatedObjectKey = &kAssociatedObjectKey; ,使用 kAssociatedObjectKey 作为 key 值;
(3)用 selector ,使用 getter 方法的名称作为 key 值。
常用方法
1.(同一个类中传递任意参数..blcok)**test
- (void)button blcok:(butBlock)block {
[self addTarget:self action:@selector(buttonActioddd:) forControlEvents:UIControlEventTouchUpInside];
objc_setAssociatedObject(self, &buttonKey, block, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (void)buttonActioddd:(UIButton *)button {
butBlock block = objc_getAssociatedObject(self, &buttonKey);
block();
}
2.category增加实例变量
@property (nonatomic,strong) NSString *stringProperty;
-(void)setStringProperty:(NSString *)stringProperty{
objc_setAssociatedObject(self, StringProperty, stringProperty, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(NSString *)stringProperty{
return objc_getAssociatedObject(self, StringProperty);
}
优点:
1.简化代码
2.让代码层次清晰
3.充分利用对象与属性的拥有关系