美文网首页OC语言
iOS 关联对象笔记

iOS 关联对象笔记

作者: 人魔七七 | 来源:发表于2019-01-10 16:50 被阅读8次

    方法

    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 获取关联对象
    • 移除所有关联对象

    例子

    下面AFN的一个例子

    - (AFImageDownloadReceipt *)af_activeImageDownloadReceipt {
        return (AFImageDownloadReceipt *)objc_getAssociatedObject(self, @selector(af_activeImageDownloadReceipt));
    }
    
    - (void)af_setActiveImageDownloadReceipt:(AFImageDownloadReceipt *)imageDownloadReceipt {
        objc_setAssociatedObject(self, @selector(af_activeImageDownloadReceipt), imageDownloadReceipt, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    

    注意:对于key的写法有很多种参考下面链接,个人比较喜欢上述的写法

    存储位置

    关联对象由AssociationsManager管理并在AssociationsHashMap存储,所有对象的关联内容都在同一个容器中,这个全局容器的数据结构类似下图。


    注意:为什么不放在本类中,由于类的内存布局已预先设置,关联对象添加的属性或者变量不能放在原有类结构上,找一个全局容器以key value方式存储。

    如何清除一个关联对象的值?

    如图,把value设置为nil,走的就是图中else分支,就可以擦除。

    注意:你可以会在刚开始接触对象关联时想要尝试去调用 objc_removeAssociatedObjects() 来进行删除操作,但如文档中所述,你不应该自己手动调用这个函数。

    苹果文档解释如下:
    此函数的主要目的是在“初试状态”时方便地返回一个对象。你不应该用这个函数来删除对象的属性,因为可能会导致其他客户对其添加的属性也被移除了。规范的方法是:调用 objc_setAssociatedObject 方法并传入一个 nil 值来清除一个关联。

    关联对象本质的总结:

    根据图中由下往上,
    1)首先,传入的value(“Hello”)和policy(OBJC_ASSOCIATION_COPY_NONATOMIC)封装成ObjcAssociation这样一个结构;
    2)通过ObjcAssociation和selector的key 建立的一个映射结构ObjcAssociationMap;
    3)再把2)中的ObjcAssociationMap作为全局容器AssociatonsHashMap的一个value,对应的key为DISGIUISE(obj)。

    参考链接

    关联对象相关面试问题
    关联对象 AssociatedObject 完全解析

    相关文章

      网友评论

        本文标题:iOS 关联对象笔记

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