分类、类扩展、继承的总结讲述了分类,介绍到分类可以添加属性,但是属性的get、set方法需要通过runtime的关联对象进行添加。
还有一个问题是,是否可以给分类添加“成员变量”?(
面试问题
)
可以,通过关联对象添加。怎么擦除一个关联对象?(```面试问题````)
把这个key关联的值设置为nil。
objc_setAssociatedObject(self,@selector(text), @"hello", OBJC_ASSOCIATION_COPY_NONATOMIC);
NSLog(@"获取设置的值:%@",objc_getAssociatedObject(self, @selector(text)));// 获取设置的值:hello
objc_setAssociatedObject(self,@selector(text), nil, OBJC_ASSOCIATION_COPY_NONATOMIC);
NSLog(@"值被擦除后:%@",objc_getAssociatedObject(self, @selector(text)));//值被擦除后:(null)
- 这个“成员变量”添加到哪里了呢?(
面试问题
)
添加到一个全局容器当中。
关联对象由
AssociationsManafer
管理在AssociationsHashMap
中;
所有对象的关联内容都在同一个全局容器
中
详细了解这个全局容器,我们需要查看关联对象的本质。
关联对象的本质
如下,我们关联对象都是通过这个方法。
/*
obj:为哪个对象关联
key:关联的key
value:关联的值
policy:什么方式存储,copy、retain、assign
*/
objc_setAssociatedObject(id obj, const void * _Nonnull key, id _Nullable value, objc_AssociationPolicy policy)
我们为当前对象进行关联,key为@selector(text),值为"hello",类型为copy类型
objc_setAssociatedObject(self,@selector(text), @"hello", OBJC_ASSOCIATION_COPY_NONATOMIC);
关联本质:
如下图
- 有一个结构体ObjcAssociation,存储着value值"hello"、存储策略OBJC_ASSOCIATION_COPY_NONATOMIC;
- 然后把ObjcAssociation作为value、和key存储到ObjctAssociationMap中。
- 最后把这个ObjctAssociationMap放到大容器AssociationMap中。
如下,一个大容器AssociationMap中有很多对象为key存储ObjctAssociationMap。每一个ObjctAssociationMap中有很多个ObjcAssociation。