美文网首页
关联对象底层结构

关联对象底层结构

作者: 差不多先生__ | 来源:发表于2022-04-20 17:01 被阅读0次

关联对象的方法

runtime给我们提供了三个关于关联对象的方法,如下。点击查看如何添加关联对象

//设置关联对象的方法
OBJC_EXPORT void
objc_setAssociatedObject(id _Nonnull object, const void * _Nonnull key,
                         id _Nullable value, objc_AssociationPolicy policy);

//获取关联对象的方法
OBJC_EXPORT id _Nullable
objc_getAssociatedObject(id _Nonnull object, const void * _Nonnull key);

//删除关联对象的方法
OBJC_EXPORT void
    objc_removeAssociatedObjects(id _Nonnull object);

了解了这三个方法,我们需要先记住添加关联对象方法的四个参数,分别是objectkeyvaluepolicy,这四个参数的含义分别是:
1.object源对象(一般用self)
2.key关联时的用来标记是哪一个属性的key(因为你可能要添加很多属性,这里咱们填写的是&nameKey)
3.value关联的对象(name)
4.policy一个关联策略

关联对象的核心对象

首先我们要知道的是关联对象并不是存储在被关联对象本身内存中,它是统一存储在一个全局的AssociationsManager中,而实现关联对象技术的核心对象有四个,分别是:

  • AssociationsManager
  • AssociationsHashMap
  • ObjectAssociationMap
  • ObjcAssociation

AssociationsManager的结构

class AssociationsManager {
    // associative references: object pointer -> PtrPtrHashMap.
    static AssociationsHashMap *_map;
public:
    AssociationsManager()   { AssociationsManagerLock.lock(); }
    ~AssociationsManager()  { AssociationsManagerLock.unlock(); }
    
    AssociationsHashMap &associations() {
        if (_map == NULL)
            _map = new AssociationsHashMap();
        return *_map;
    }
};

其中static AssociationsHashMap *_map;是我们真正要关心的内容,public里面的内容是一个锁和如果没有AssociationsHashMap对象就新创建一个并返回其地址。

AssociationsHashMap的结构

class AssociationsHashMap : public unordered_map<disguised_ptr_t, ObjectAssociationMap *, DisguisedPointerHash, DisguisedPointerEqual, AssociationsHashMapAllocator> {
    public:
        void *operator new(size_t n) { return ::malloc(n); }
        void operator delete(void *ptr) { ::free(ptr); }
    };

其中我们需要关心的参数有两个分别是disguised_ptr_tAssociationsManager,其中disguised_ptr_t是我们设置关联对象时的那个object,并且这个objectAssociationsManager用作为key,ObjectAssociationMap是存储的哪个对象,并作为value,这个对象里面可能有多个关联对象。

ObjectAssociationMap的结构

 class ObjectAssociationMap : public std::map<void *, ObjcAssociation, ObjectPointerLess, ObjectAssociationMapAllocator> {
    public:
        void *operator new(size_t n) { return ::malloc(n); }
        void operator delete(void *ptr) { ::free(ptr); }
    };

这里面我们需要关心的参数有两个分别是void *ObjcAssociation,其中void *是我们设置关联对象时传递的参数key,这个key也是我们某一个关联对象的key,而ObjcAssociation就是我们最终关联的那个对象了。

ObjcAssociation的结构

class ObjcAssociation {
        uintptr_t _policy;
        id _value;
    public:
        ObjcAssociation(uintptr_t policy, id value) : _policy(policy), _value(value) {}
        ObjcAssociation() : _policy(0), _value(nil) {}

        uintptr_t policy() const { return _policy; }
        id value() const { return _value; }
        
        bool hasValue() { return _value != nil; }
    };

这里面我们需要关心的参数有两个分别是uintptr_t _policy;id _value;,其中_value是我们关联对象的值,比如我们关联的是字符串,这个就是那个字符串,而_policy就是关联的策略。

以上结构中,public:里面都是该结构的一些方法,不必过度关心,下面为用一个图来表示整个结构的关系,我把设置关联对象的那个方法再次贴到下面,为了方便看,我会做好分行,且不写返回值void

    objc_setAssociatedObject(id _Nonnull object,
                             const void * _Nonnull key,
                             id _Nullable value,
                             objc_AssociationPolicy policy);
关联对象结构.png

相关文章

  • iOS原理篇(四):关联对象

    关联对象的使用场合 关联对象的基本使用 关联对象的底层原理 一、关联对象的使用场合默认情况下,因为分类底层结构的限...

  • 关联对象底层结构

    关联对象的方法 runtime给我们提供了三个关于关联对象的方法,如下。点击查看如何添加关联对象[https://...

  • iOS底层原理总结 - 关联对象实现原理

    iOS底层原理总结 - 关联对象实现原理 iOS底层原理总结 - 关联对象实现原理

  • 关联对象(给分类添加成员变量)

    ?默认情况下,因为分类底层结构的限制,不能田间成员变量到分类中。但可以通过关联对象来间接实现?关联对象提供了以下a...

  • 关联对象总结

    默认情况下,因为分类底层结构的限制,不能添加成员变量到分类中。但可以通过关联对象来间接实现 关联对象提供了以下AP...

  • iOS底层之类的结构分析

    从iOS底层之isa结构分析及关联类我们探究了类的实例对象的内存结构,对象指针的首地址存储了isa,也就是存储了类...

  • 关联对象

    关联对象的方式 关联对象源码基本思路 关联对象的结构:AssociationsHashManager // Ass...

  • 探寻OC关联对象

    简单应用 关联对象常用的API如下: 默认情况下,因为分类底层结构的限制,不能添加成员变量到分类中。但可以通过关联...

  • iOS底层探索之类的结构(上)

    回顾 在之前的几篇博客里面,我们知道了对象的本质是结构体(iOS底层探索之对象的本质和类的关联特性initIsa(...

  • 底层原理:关联对象

    在分类中声明属性的时候,只会自动生成方法的声明,并不会生成方法的实现和成员变量,举例说明: 即通过上述代码声明 w...

网友评论

      本文标题:关联对象底层结构

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