默认情况下,因为分类底层结构只有属性列表和协议列表方法列表等,但是偏偏没有成员变量列表,所以分类不能添加成员变量,但是可以通过关联对象来间接实现,但并不是这个对象真正意义上的成员变量。虽然分类的属性自动生成了set和get方法的声明,但是并没有生成set和get方法的实现。
1.添加关联对象
void objc_setAssociatedObject(id object, const void * key, id value, objc_AssociationPolicy policy)
object:要“添加”成员变量的对象(这里可以是类对象,但是一般传入的是实例对象)。
key:整个程序唯一存在的标识,一般用get方法的地址值做key,与获得关联对象的key成对使用,如@selector(age)。
value:要传入的值。
policy:关联对象的策略。
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
2.移除所有的关联对象
void objc_removeAssociatedObjects(id object)
3.关联对象的原理
他们的关系如下图
AssociationsManager是全局统一的,AssociationsHashMap也是唯一的。
4.获得关联对象
id objc_getAssociatedObject(id object, const void * key)
首先通过对象获得 ObjectAssociationMap,然后通过key得到ObjectAssociation对象,该对象存有value和policy。
所以,关联对象并不是真正意义上的添加变量,只是显现了同样的效果