一.分类里面添加属性,不会生成set\get方法实现;以及成员变量;只是声明了set、get函数;
二.给分类间接添加属性:
方法一:
-(void)setName:(NSString*)name{
objc_setAssociatedObject(self, &LZHNameKey, name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)name{
return objc_getAssociatedObject(self, &LZHNameKey);
}
参数1:关联的对象;参数2:关联的key;参数3:关联属性的值value
参数4: 关联策略:
/**
OBJC_ASSOCIATION_ASSIGN assign
OBJC_ASSOCIATION_RETAIN_NONATOMIC strong,nonatomic
OBJC_ASSOCIATION_COPY_NONATOMIC copy ,nonatomic
OBJC_ASSOCIATION_RETAIN strong,atomic
OBJC_ASSOCIATION_COPY copy,atomic
*/
方法二:
@“name” 是地址,是存放到常量区。取出来的地址是唯一的;
-(void)setName:(NSString *)name{
objc_setAssociatedObject(self, @"name", name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)name{
return objc_getAssociatedObject(self, @"name");
}
方法三:
-(void)setName:(NSString *)name{
objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)name{
return objc_getAssociatedObject(self,@selector(name));
}
方法四:
-(void)setName:(NSString *)name{
objc_setAssociatedObject(self, @selector(name), name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- (NSString *)name{
return objc_getAssociatedObject(self,_cmd);
}
一般建议使用第三种方式来关联;
三:底层实现原理分析:
1.objc_setAssociatedObject底层实现主要是由4个核心对象实现
AssociationsManager
AssociationsHashMap
ObjectAssociationMap
ObjcAssociation
1). AssociationsManager里面存储着AssociationsHashMap对象;
class AssociationsManager {
static AssociationsHashMap *_map;
};
2). AssociationsHashMap里面存放着key-vlaue形式的disguised_ptr_t为key(就是外面参数传入的object对象的内存地址), ObjectAssociationMap 为value值;
class AssociationsHashMap : public unordered_map {
3). ObjectAssociationMap里面存放着key-vlaue形式的 void * 为key(就是外面传入的第二个参数,就是LZHNameKey的地址), ObjcAssociation为value值;
class ObjectAssociationMap : public std::map {
4). ObjcAssociation 存放着 objc_setAssociatedObject的策略和value值,也是外面调用的时候传入进来的;
class ObjcAssociation {
uintptr_t _policy;(就是外面传入的第四个参数,就是关联的策略);
id _value; (就是外面传入的第三个参数,就是属性的值的地址)
};
2.设置关联对象的value为nil,就相当于是移除关联对象;
移除对象所有的关联对象函数;调用系统api
objc_removeAssociatedObjects(<#id _Nonnull object#>)