美文网首页
关联属性

关联属性

作者: 小冰山口 | 来源:发表于2024-03-10 13:12 被阅读0次
思考, 如何实现给分类"添加成员变量"?

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

关联对象提供了以下API

  • 添加关联对象

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 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_getAssociatedObject(self, _cmd)

一般用第四种: 使用get方法的@selecor作为key

再来看一下: objc_AssociationPolicy
图片来源小码哥

我们看下objc_setAssociatedObject底层究竟做了些什么:

image.png

直接调用了_object_set_associative_reference:

image.png

所以, 这个数据存储的流程就是:
运行时全局维护了一个AssociationsManager管理类, 那么这个管理类里又有一个AssociationsHashMap
这个AssociationsHashMap是通过object为key存储数据的, 也就是说, 一个对象对应一条数据, 那么每个关联的对象都对应一条数据.
这条数据就又是一个hashMap, 即: ObjectAssociationMap
那么ObjectAssociationMap里面又是什么呢?
ObjectAssociationMap以你传入的keykey, 值是由你传入的policyvalue组成的结构体为值

如下图所示:


图片来源小码哥

如果设置valuenil, 会移除掉这个key吗?

image.png
如果通过key找到了, 就会直接删除这个value, 如果整个关联对象中已经不存在需要关联的值, 那就会把整个关联对象都删掉.

我们再来看看objc_getAssociatedObject

image.png

内部调用了_object_get_associative_reference

image.png

可以很清楚的看到逻辑:

  • 先通过object, 找到associations这个hashmap里的值, 也是一个hashmap, 叫做ObjectAssociationMap

  • 再通过key找到refs里的值, 就是association, 里面存储了policyvalue值, 最后返回的是association里的autoreleaseReturnedValue值.

而移除所有关联对象, objc_removeAssociatedObjects 就是根据objectkey, 找到对应的hashMap, 然后再删掉, 如下图所示:

image.png

相关文章

  • 关联属性

    分类中不可以添加成员变量 分类中可以声明属性,分类中声明属性只会生成方法的声明,但不会生成成员变量和方法的实现。 ...

  • OC属性关联的实现原理

    OC中在分类中添加属性用属性关联技术来实现存取值的: 那么系统的属性关联功能是如何实现的呢? 属性关联怎么存储对象...

  • Runtime 关联对象, 可在分类中添加属性

    Runtime 关联对象, 可在分类中添加属性 关联 API 如下 设置关联值 获取关联值 取消关联 关联策略

  • UIAlertView关联属性 + 分类

    UIAlertView关联属性 UIAlertView 分类 增加block属性

  • runtime关联属性

    前言 在开发中经常需要给已有的类添加方法和属性,但是Objective-C是不允许给已有类通过分类添加属性的,因为...

  • runtime - 关联属性

    我们知道苹果不允许我们自己给已经存在的类通过分类添加方法的,但是有时候我们确实需要给某个类从而分类添加属性,那么我...

  • runtime关联属性

    类别是开发中常常使用的东西,但是偶尔需要添加属性,这个就需要使用继承来实现,但是如果是只有一两个属性的话,也太过麻...

  • Swift 属性(Properties)详解

    属性将值与特定类,结构或枚举相关联; 存储和计算属性通常与特定类型的实例相关联。但是属性也可以和类型本身相关联(类...

  • iOS开发_运行时的简单使用

    动态添加属性/*产生关联,让某个对象(name)与当前对象的属性(name)产生关联参数1: id object ...

  • Laravel预加载

    当通过属性访问 Eloquent 关联时,该关联数据会被「延迟加载」。意味着该关联数据只有在你使用属性访问它时才会...

网友评论

      本文标题:关联属性

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