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 , 存取的时候两层处理。