关联对象

分类、类扩展、继承的总结讲述了分类,介绍到分类可以添加属性,但是属性的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);

关联本质:

如下图

  1. 有一个结构体ObjcAssociation,存储着value值"hello"、存储策略OBJC_ASSOCIATION_COPY_NONATOMIC;
  2. 然后把ObjcAssociation作为value、和key存储到ObjctAssociationMap中。
  3. 最后把这个ObjctAssociationMap放到大容器AssociationMap中。
关联对象的本质

如下,一个大容器AssociationMap中有很多对象为key存储ObjctAssociationMap。每一个ObjctAssociationMap中有很多个ObjcAssociation。

关联对象的本质
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容