美文网首页
分类中添加属性的实现原理

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

作者: 初灬终 | 来源:发表于2019-10-13 06:32 被阅读0次

    相关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);
    }
    

    相关文章

      网友评论

          本文标题:分类中添加属性的实现原理

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