关联对象

2018-11-14  本文已影响6人  小行为

能否为分类添加 “成员变量” ?

// 添加关联对象
id   objc_getAssociateObject(id object, const void * key)
/* objc_Association 关联策略   */
id   objc_setAssociateObject(id object, const void * key, id value , objc_Association )
//移除关联对象
id objc_removeAssociatedObject(id object)

为分类所添加的成员变量添加在哪里?

所有对象的关联内容都在同一个全局容器内
关联对象的本质

setobjc_association(处理 Key) -> 
objectAssociationMap (#selector  -作为 key) - > 
AssociationHashMap(全局容器   -key value 关联 和对象指针 )  -> 

流程图:

屏幕快照 2018-11-14 下午4.55.34.png

源码分析:


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

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

#endif


void objc_removeAssociatedObjects(id object) 
{
#if SUPPORT_GC
    if (UseGC) {
        auto_zone_erase_associative_refs(gc_zone, object);
    } else 
#endif
    {
        if (object && object->hasAssociatedObjects()) {
            _object_remove_assocations(object);
        }
    }
}

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;
        AssociationsHashMap &associations(manager.associations());
        disguised_ptr_t disguised_object = DISGUISE(object);
        if (new_value) {
            // break any existing association.
            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 {
            // 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);
                }
            }
        }
    }
    // release the old value (outside of the lock).
    if (old_association.hasValue()) ReleaseValue()(old_association);
}

转换成类似JSON


屏幕快照 2018-11-14 下午5.01.51.png
上一篇 下一篇

猜你喜欢

热点阅读