分类中添加属性的实现原理

相关Class或Struct

AssociationsManager:全局唯一的关联对象管理者。

AssociationsHashMap:全局关联对象的hashMap,{DISGUISE(object):ObjectAssociationMap}

ObjectAssociationMap:某个对象的关联对象hashMap。{key:ObjcAssociation}

ObjcAssociation:关联对象的封装。{policy:0,value:"text"}

数据格式

{
    "0x4565412387": {
        "@selector(text)": {
            "policy": "copy",
            "value": "text"
        },
        "@selector(color)": {
            "policy": "retain",
            "value": "color"
        }
    },
    "0x1535342987": {
        "@selector(text)": {
            "policy": "copy",
            "value": "text"
        }
    }
}

}

源码(主干)

void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) {
    _object_set_associative_reference(object, (void *)key, value, policy);
}
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;
    {
        AssociationsManager manager;
        AssociationsHashMap &associations(manager.associations());
        disguised_ptr_t disguised_object = DISGUISE(object);

        //  传入的value不为空
        if (new_value) {
            
            // break any existing association.
            //在AssociationsHashMap迭代查找ObjectAssociationMap
            //在AssociationsHashMap找到了ObjectAssociationMap
            AssociationsHashMap::iterator i = associations.find(disguised_object);
            if (i != associations.end()) {
                // secondary table exists
                //AssociationsHashMap中是以disguised_object为key,ObjectAssociationMap为value
                //i->second表示取value
                ObjectAssociationMap *refs = i->second;

                ObjectAssociationMap::iterator j = refs->find(key);
                if (j != refs->end()) {
                    //ObjcAssociation对象原本有值,重新赋值。
                    old_association = j->second;
                    j->second = ObjcAssociation(policy, new_value);
                } else {
                    //ObjcAssociation对象原本没值,赋新值。
                    (*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 == nil
            // setting the association to nil breaks the association.
            //先以对象为key,在全局AssociationsHashMap查找
            AssociationsHashMap::iterator i = associations.find(disguised_object);
            //如果在AssociationsHashMap找到了
            if (i !=  associations.end()) {
                
                ObjectAssociationMap *refs = i->second;

                //ObjectAssociationMap中是以传入的key为key,以ObjcAssociation为value
                ObjectAssociationMap::iterator j = refs->find(key);
                if (j != refs->end()) {
                    old_association = j->second;
                    //如果传入value == nil,将会把传入的key,value键值对擦除。
                    refs->erase(j);
                }
            }
        }
    }
    // release the old value (outside of the lock).
    if (old_association.hasValue()) ReleaseValue()(old_association);
}

你可能感兴趣的:(分类中添加属性的实现原理)