分类与类扩展以及关联对象

category 分类


专门用来各类添加新的方法。

不能给类添加成员属性,添加了成员变量,也无法取到(注意:其实可以通过runtime给分类添加属性)。

注意:可以用runtime给分类添加属性

分类中用@property定义变量,只会生成变量的getter setter方法的声明,不能生成方法实现和带下划线的成员变量。

extension 类拓展

可以说成是特殊的分类,也称作匿名分类。

可以给类添加成员属性,但是是私有变量。

可以给类添加方法,也是私有方法。

关联对象

设值:

深入分析一下这个方法

1.DisguisedPtr:封装object对象,用来查询map的key值

2.ObjcAssociation:封装策略和值

3.AssociationsManager:里面包含一个静态map,用来处理关联对象的表

4.AssociationsHashMap:一个map,初始化传入的是AssociationsManager对象中的静态表,

我们可以发现AssociationsManager可以有多个。下面就到了AssociationsHashMap,这个是HashMap这是个哈希表,这个是唯一的。因为AssociationsManager方法里看到AssociationsHashMap是通过_mapStorage.get()方法获得,而_mapStorage是通过static声明的,是静态变量,也就是AssociationsHashMap是通过静态变量_mapStorage获取的,所以是全场唯一的。

5.association.acquireValue();使用传入的策略对value值进行引用计算的处理

如果是retain类型就调用objc_retain,如果是copy类型就发送copy消息。也就是对我们的策略类型进行处理

auto refs_result = associations.try_emplace(disguised, ObjectAssociationMap{});从静态map中通过object取出一个包含两个数据的结构

if (refs_result.second) 如果是对象的第一次关联,则对对象的isa关联变量设值为true

8.refs.try_emplace(key, std::move(association)); 通过object 找到静态表(MAP)中对应的表(MAP),在通过传入的key进行设值value。


关联对象设值流程:

1: 创建⼀个 AssociationsManager 管理类

2: 获取唯⼀的全局静态哈希Map

3: 判断是否插⼊的关联值是否存在

    3.1: 存在⾛第4步

    3.2: 不存在就⾛ : 关联对象插⼊空流程

4: 创建⼀个空的 ObjectAssociationMap 去取查询的键值对

5: 如果发现没有这个 key 就插⼊⼀个 空的 BucketT进去 返回

6: 标记对象存在关联对象

7: ⽤当前 修饰策略 和 值 组成了⼀个 ObjcAssociation 替换原来 BucketT 中的空

8: 标记⼀下 ObjectAssociationMap 的第⼀次为 false

关联对象插⼊空流程:

1: 根据 DisguisedPtr 找到 AssociationsHashMap 中的 iterator 迭代查询器

2: 清理迭代器

3: 其实如果插⼊空置 相当于清除

取值:

关联对象取值流程:

1: 创建⼀个 AssociationsManager 管理类

2: 获取唯⼀的全局静态哈希Map

3: 根据 DisguisedPtr 找到 AssociationsHashMap 中的 iterator 迭代查询器

4: 如果这个迭代查询器不是最后⼀个 获取 : ObjectAssociationMap (这⾥有策略和value)

5: 找到ObjectAssociationMap的迭代查询器获取⼀个经过属性修饰符修饰的value

6: 返回_value

关联对象本质

 关联对象底层实现:其实就是两层哈希map , 存取的时候两层处理。

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