有时候咱们须要在现有的类存放一些额外的信息,一般的作法是继承一个子类,而后定义新增长的属性,然而若是咱们为每一个须要的类都添加一个类显得太麻烦了,objc提供了一个关联属性的特性,能够给一个对象关联一个属性(作过.NET的朋友必定熟悉附加属性,objc的关联属性与.NET的附加属性有点相似相似)函数
使用关联属性很简单,下面是几个主要的函数atom
//设置关联属性
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)
咱们声明属性的时候会声明:copy,retain,assign 内存管理方式,在设置关联属性的时候也有,即 objc_setAssociatedObject 的第四个参数spa
关联类型 | 等效@property属性 |
OBJC_ASSOCIATION_ASSIGN指针 |
assign |
OBJC_ASSOCIATION_RETAIN_NONATOMICcode |
nonatomic, retainorm |
OBJC_ASSOCIATION_COPY_NONATOMIC对象 |
nonatomic, copy |
OBJC_ASSOCIATION_RETAINblog |
retain |
OBJC_ASSOCIATION_COPY继承 |
copy |
关联属性的附加至关于NSDictionary,经过键值对存储,可是有一点跟NSDictionary不同的是,设置关联对象所用的键(key)是不透明指针(opaque pointer),NSDictionary判断两个Key的isEqual方法判断是否相等,而关联对象只判断两个key的地址是否相等,而不会比较对象具体的值内存
看看下面例子
NSString *key1 = @"aaa"; NSString *key2 = [NSString stringWithFormat:@"aaa"]; NSString *key3 = @"bbb"; NSObject *obj = [[NSObject alloc] init]; objc_setAssociatedObject(obj, key1.UTF8String, @"aaa1", OBJC_ASSOCIATION_RETAIN_NONATOMIC); objc_setAssociatedObject(obj, key2.UTF8String, @"aaa2", OBJC_ASSOCIATION_RETAIN_NONATOMIC); objc_setAssociatedObject(obj, key3.UTF8String, @"bbb", OBJC_ASSOCIATION_RETAIN_NONATOMIC); id value1 = objc_getAssociatedObject(obj, key1.UTF8String); id value2 = objc_getAssociatedObject(obj, key2.UTF8String); id value3 = objc_getAssociatedObject(obj, key3.UTF8String); NSLog(@"value1 = %@", value1); NSLog(@"value2 = %@", value2); NSLog(@"value3 = %@", value3);
输出
这里的key1和key2都是@"aaa",可是取出来的value1和value2却不同,这是由于key1和key2的地址不同,在匹配的时候关联对象视为不一样的key,因此一般咱们在定义关联对象的key的时候使用静态全局变量做为键,这样能够保证地址一致
static char *key = "aaa"; NSObject *obj = [[NSObject alloc] init]; objc_setAssociatedObject(obj, key, @"aaa1", OBJC_ASSOCIATION_RETAIN_NONATOMIC); objc_setAssociatedObject(obj, key, @"aaa2", OBJC_ASSOCIATION_RETAIN_NONATOMIC); id value1 = objc_getAssociatedObject(obj, key); //把原有的值覆盖
id value2 = objc_getAssociatedObject(obj, key); NSLog(@"value1 = %@", value1); NSLog(@"value2 = %@", value2);
参考文章: