美文网首页
iOS-Category管理对象的原理

iOS-Category管理对象的原理

作者: 翀鹰精灵 | 来源:发表于2020-12-29 17:41 被阅读0次

    上次我们说到 iOS-Category添加成员变量 是通过 objc_setAssociatedObjectobjc_getAssociatedObject来实现的,我们一起来探究下这两个方法的底层实现。

    我们可以通过下载开源的runtime的代码,来查看一下底层的实现方法。Runtime的开源代码

    【_object_set_associative_reference】

    01.jpg
    【_object_get_associative_reference】
    02.jpg

    通过上图的方法可以看到,实现关联对象技术的核心对象为一下四个:

    AssociationsManager
    AssociationsHashMap
    ObjectAssociationMap
    ObjcAssociation

    这四个的关系如下所示:

    class AssociationsManager {
        ...
        AssociationsHashMap &get() {
            return _mapStorage.get();
        }
        ...
    };
    
    typedef DenseMap<DisguisedPtr<objc_object>, ObjectAssociationMap> AssociationsHashMap;
    
    
    typedef DenseMap<const void *, ObjcAssociation> ObjectAssociationMap;
    
    
    class ObjcAssociation {
        uintptr_t _policy;
        id _value;
    };
    
    03.jpg 04.jpg

    /**
    ① id object --相当于Person对象
    ② const void *key 对应ObjectAssociationMap
    ③ id value --ObjcAssociation中的value
    ④ uintptr_t policy--ObjcAssociation中的policy
    */
    _object_set_associative_reference(id object, const void *key, id value, uintptr_t policy)

    由上图可知,关联对象并不是放在原来对象里面,而是通过runtime自己维护了一个Map。

    【总结】:

    • 关联对象并不是存储在被关联对象本身内存中;
    • 关联对象存储在全局统一的一个AssociationsManager中
    • 设置关联对象为nil ,就相当于移除当前关联对象;
    • 调用objc_removeAssociatedObjects(<#id _Nonnull object#>)方法,移除Person类中所有的关联对象。

    相关文章

      网友评论

          本文标题:iOS-Category管理对象的原理

          本文链接:https://www.haomeiwen.com/subject/wmoznktx.html