美文网首页iOS面试总结
OC语言之category_关联对象的本质源码解析

OC语言之category_关联对象的本质源码解析

作者: Jimmy_L_Wang | 来源:发表于2019-06-14 22:30 被阅读0次

关联对象

能否给分类添加"成员变量"?

使用关联对象技术为分类添加"成员变量"

关联对象添加的"成员变量"添加到了那里?

关联对象的本质

关联对象由系统提供的AssociationsManager类管理并在其成员变量AssociationsHashMap中存储。

所有对象的关联内容都在同一个全局容器中(不同的类添加的分类成员变量也是放在这里)。

关联对象的本质.png

源码解析

源码是objc-runtime.mm

id objc_getAssociatedObject(id object, const void *key) {
    return _object_get_associative_reference(object, (void *)key);
}


void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) {
    _object_set_associative_reference(object, (void *)key, value, policy);
}


void objc_removeAssociatedObjects(id object) 
{
    if (object && object->hasAssociatedObjects()) {
        _object_remove_assocations(object);
    }
}
static id acquireValue(id value, uintptr_t policy) {
  //根据policy决定消息发送的类型
    switch (policy & 0xFF) {
    case OBJC_ASSOCIATION_SETTER_RETAIN:
        return objc_retain(value);
    case OBJC_ASSOCIATION_SETTER_COPY:
        return ((id(*)(id, SEL))objc_msgSend)(value, SEL_copy);
    }
    return value;
}

void _object_set_associative_reference(id object, void *key, id value, uintptr_t policy) {
    // retain the new value (if any) outside the lock.
    ObjcAssociation old_association(0, nil);
    id new_value = value ? acquireValue(value, policy) : nil;//见上面函数实现
    {
      //关联对象管理类,C++实现的一个类
        AssociationsManager manager;
      //获取其维护的一个Hashmap,我们可以理解为是一个字典
      //=============
      //是一个全局对象
      //=============
        AssociationsHashMap &associations(manager.associations());
      //DISGUISE函数对指针地址进行按位取反~,来作为全局容器当中某个对象的key
      //inline disguised_ptr_t DISGUISE(id value) { return ~uintptr_t(value); }
        disguised_ptr_t disguised_object = DISGUISE(object);
        if (new_value) {//value不为空
            // break any existing association.
          //根据对象指针查找对应的一个ObjectAssociationMap结构的Map
            AssociationsHashMap::iterator i = associations.find(disguised_object);
            if (i != associations.end()) { //找到
                // secondary table exists
                ObjectAssociationMap *refs = i->second;
                ObjectAssociationMap::iterator j = refs->find(key);
                if (j != refs->end()) {
                    old_association = j->second;
                    j->second = ObjcAssociation(policy, new_value);
                } else {
                    (*refs)[key] = ObjcAssociation(policy, new_value);
                }
            } else {//未找到
                // create the new association (first time).
                ObjectAssociationMap *refs = new ObjectAssociationMap;
                associations[disguised_object] = refs;
                (*refs)[key] = ObjcAssociation(policy, new_value);
                object->setHasAssociatedObjects();
            }
        } else {//value为空
            // setting the association to nil breaks the association.
            AssociationsHashMap::iterator i = associations.find(disguised_object);
            if (i !=  associations.end()) {
                ObjectAssociationMap *refs = i->second;
                ObjectAssociationMap::iterator j = refs->find(key);
                if (j != refs->end()) {
                    old_association = j->second;
                    refs->erase(j); //擦除
                  //如果想撤销一个已经关联到对象的一个值时,可以采取value传值为nil的方式来实现
                }
            }
        }
    }
    // release the old value (outside of the lock).
    if (old_association.hasValue()) ReleaseValue()(old_association);
}
关联对象的本质02.png

相关文章

  • OC语言之category_关联对象的本质源码解析

    关联对象 能否给分类添加"成员变量"? 使用关联对象技术为分类添加"成员变量" 关联对象添加的"成员变量"添加到了...

  • OC关联对象源码解析

    OC关联对象源码解析 默认情况下分类是不能添加成员变量的,我们可以利用Runtime通过关联对象间接实现给分类添加...

  • 四、isa 指针关联类

    主要内容:1.OC对象的本质2.isa 与 类的关联原理3.isa 与 类的关联验证 1.OC对象的本质 先了解编...

  • 探寻block的本质

    转自:探寻block的本质拓展:探寻OC对象的本质iOS底层原理总结 - 关联对象实现原理iOS底层原理总结 - ...

  • iOS源码解析—YYModel(NSObject+YYModel

    概述 ​ iOS源码解析—YYModel(YYClassInfo)分析了如何根据OC的Class对象构建...

  • OC 与 Swift

    OC对象的本质(上):OC对象的底层实现原理OC对象的本质(中):OC对象的种类OC对象的本质(下):详解isa&...

  • OC对象的本质(中)—— OC对象的种类

    OC对象的本质(上):OC对象的底层实现原理OC对象的本质(中):OC对象的种类OC对象的本质(下):详解isa&...

  • OC对象的本质(下)—— 详解isa&supercl

    OC对象的本质(上):OC对象的底层实现原理OC对象的本质(中):OC对象的种类OC对象的本质(下):详解isa&...

  • OC_底层_isa探究

    isa与类关联的原理 OC对象的本质 先简单简介llbd相关知识: 在代码中探索对象本质: 在 main.cpp ...

  • 聊一聊对象(一)

    Apple源码[opensource.apple.com/tarballs/] iOS开发之OC对象本质[http...

网友评论

    本文标题:OC语言之category_关联对象的本质源码解析

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