美文网首页
关联对象

关联对象

作者: 英雄出少年 | 来源:发表于2019-05-13 18:19 被阅读0次

如何实现给分类“添加成员变量”?

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

尝试过程

1、添加全局变量可以保存值,但是是全局性的会覆盖以前的值


@implementation TGPerson (Test)

intweight_;

- (void)setWeight:(int)weight {
    weight_= weight;
}

- (int)weight {
    return weight_;
}

@end

2、 添加全局字典,线程安全


@implementation TGPerson (Test)

NSMutableDictionary *weights_;
+ (void)load {
    weights_ = [NSMutableDictionary dictionary];
}

- (void)setWeight:(int)weight {
    NSString *key = [NSString stringWithFormat:@"%p", self];
    weights_[key] =@(weight);
}

- (int)weight {
    NSString *key = [NSString stringWithFormat:@"%p", self];
    return [weights_[key] intValue];
}

@end

2、关联对象

  • 设置关联对象
void objc_setAssociatedObject(id object,const void * key,  id value,objc_AssociationPolicy policy)
  • 获取关联对象

id objc_getAssociatedObject(id object,const void * key)

  • 移除所有的关联对象

void objc_removeAssociatedObjects(id object)

key的常见用法

  • static void *MyKey = &MyKey;(用自己的地址值)
objc_setAssociatedObject(obj,MyKey,value,OBJC_ASSOCIATION_RETAIN_NONATOMIC)
 objc_getAssociatedObject(obj,MyKey)
  • static const char MyKey;
objc_setAssociatedObject(obj,&MyKey,value,OBJC_ASSOCIATION_RETAIN_NONATOMIC)
objc_getAssociatedObject(obj,&MyKey)
  • 使用属性名作为key
objc_setAssociatedObject(obj,@"property",value,OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_getAssociatedObject(obj,@"property");
  • 使用get方法的@selecor作为key
objc_setAssociatedObject(obj,@selector(getter),value,OBJC_ASSOCIATION_RETAIN_NONATOMIC)
objc_getAssociatedObject(obj,@selector(getter))

objc_AssociationPolicy

image

关联对象原理

关联对象核心对象

  • AssociationsManager

  • AssociationsHashMap

  • ObjectAssociationMap

  • ObjcAssociation (存放 value,policy,关联对象的值存在这个对象里)

image image image image

源码解读

objc-references.mm

classAssociationsManager {
    static AssociationsHashMap *_map;
public:
    AssociationsManager()  { AssociationsManagerLock.lock(); }
    ~AssociationsManager()  { AssociationsManagerLock.unlock(); }
    AssociationsHashMap&associations() {
        if(_map==NULL)
            _map = new AssociationsHashMap();
        return*_map;
    }
};

//objc_removeAssociatedObjects 移除关联对象
    classObjcAssociation {
        uintptr_t_policy;
        id_value;
    public:
        ObjcAssociation(uintptr_tpolicy,idvalue) :_policy(policy),_value(value) {}
        ObjcAssociation() :_policy(0),_value(nil) {}
        uintptr_t policy() const { return _policy; }
        idvalue()const{return_value; }
        boolhasValue() {return_value!=nil; }
    };
void_object_remove_assocations(idobject) {
    vector< ObjcAssociation,ObjcAllocator<ObjcAssociation> > elements;
    {
        AssociationsManager manager;
       AssociationsHashMap&associations(manager.associations());
        if(associations.size() ==0)return;
        disguised_ptr_tdisguised_object =DISGUISE(object);
        AssociationsHashMap::iterator i = associations.find(disguised_object);
        if(i != associations.end()) {
            // copy all of the associations that need to be removed.
            ObjectAssociationMap*refs = i->second;
            for(ObjectAssociationMap::iterator j = refs->begin(), end = refs->end(); j != end; ++j) {
                elements.push_back(j->second);
            }
            deleterefs;
            associations.erase(i);
        }
    }
    for_each(elements.begin(), elements.end(), ReleaseValue());
}

image

小结

  • 关联对象并不是存储在被关联对象本身内存中

  • 关联对象存储在全局的统一的一个AssociationsManager中

  • 设置关联对象为nil,就相当于是移除关联对象

  • 对关联的object没有引用,操作的是地址,object销毁 关联对象也会移除

相关文章

  • Swift 为分类增加属性objc_getAssociated

    OC 获取关联对象 Swift 获取关联对象——错误的写法 Swift 获取关联对象——正确的写法 设置关联对象 ...

  • iOS runtime关联对象 objc_setAssociat

    关联对象的作用: 关联对象可以给某个对象关联一个或者多个其他对象,这些对象通过健来区分。 创建存储关联对象objc...

  • 关联对象

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

  • 关联对象

    关联对象原理 关联对象并不是存储在被关联对象本身内存中,关联对象存储在全局的统一的一个AssociationsMa...

  • iOS 关联对象

    概述 关联对象顾名思义,就是给对象关联对象的意思,一个对象可以关联多个其他对象,这些对象通过key来区分,存储对象...

  • 关联对象

    关联对象会用被关联对象作为key,将关联对象存储到全局的哈希表里。 AssociationHashMap Asso...

  • iOS关联对象技术原理

    iOS关联对象技术原理 iOS关联对象技术原理

  • 关联对象

    分类里面添加成员变量, 分类里面是不能直接添加成员变量的,但是可以通过runtime间接添加成员变量。 为什么...

  • 关联对象

    能否为分类添加 “成员变量” ? 为分类所添加的成员变量添加在哪里? 所有对象的关联内容都在同一个全局容器内关联对...

  • 关联对象

    分类、类扩展、继承的总结讲述了分类,介绍到分类可以添加属性,但是属性的get、set方法需要通过runtime的关...

网友评论

      本文标题:关联对象

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