浅析Associated Object

Category是Objective C为程序员提供的一个强大的动态机制,它们允许程序员为已有的对象添加新的方法,即便是在没有该对象的源代码的情况下。通过它可以很方便的为已有的类来添加函数。但是Category不允许为已有的类添加新的属性或者成员变量。

通过运行时的数据结构我们可以看到,objc_class结构体中维护着objc_ivar_list的指针,这个指针指向的是类中定义的实例变量的列表。

再看看objc_category的结构体中,只有类别名,类名,实例方法,类方法和遵循的协议表,由此可以看出category类中是不能够添加成员变量的。

可以发现,苹果的category设计明显是不允许在category中添加新的成员变量。但是在项目中,这明显不能满足我们的需求,不过值得庆幸的是,我们可以通过Associated Objects来弥补这一不足。

Associated Objects 介绍

与 Associated Objects 相关的函数主要有三个,我们可以在 runtime.h 文件中找到它们的声明:

1. void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
2. id objc_getAssociatedObject(id object, const void *key)
3. void objc_removeAssociatedObjects(id object)

Object:传入关联对象的所属对象,也就是增加成员的实例对象,一般来说传入self。 key:一个唯一标记。在官方文档中推荐使用static char,当然更推荐是指针。为了便捷,一般使用selector,这样在后面getter中,我们就可以利用_cmd来方便的取出selector。 value:传入关联对象。 policy:objc_AssociationPolicy是一个ObjC枚举类型,也代表关联策略。

Associated Objects 源码浅析

那究竟关联对象是如何存储的呢?透过源码,我们看到关联对象是通过一个叫做AssociationsManager的对象来进行管理的。

在AssociationsManager中,有一个spinlock_t锁和一个AssociationsHashMap的哈希表。

然后再看objc_setAssociatedObject的源码,我们可以看懂啊AssociationsHashMap中的键为disguised_ptr_t,在得到这个指针的时候,源码中执行了DISGUISE方法,通过这个方法能够获得指向self地址的指针,即为指向对象地址的指针。然后其对应的value,便是一个存放关联对象的子哈希表。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏C#

奇妙的NULL值,你知道多少

《NULL值的多义性分析》       谈到NULL值,很多人都是很熟悉,但是深入了解后,又感觉到陌生,对其含义和用法,都无法很准确的理解。NULL在数据库和...

1845
来自专栏数据小魔方

MySQL基础入门系列之——字符与日期数据处理

今天这一篇分享MySQL中的字符串处理工具与日期时间处理,这一部分内容虽然看似不多,但是往往是输出处理中的的痛点。 我的MySQL数据库中已经建好了一个包含两列...

3479
来自专栏黑白安全

Mysql索引类型Btree和Hash的区别以及使用场景

遇到单表数据量大的时候很多开发者都会想到给相对的字段建立索引来提高性能(mysql索引的使用),但很少会去关注索引的类型该如何选择,在mysql中支持有两种类型...

1863
来自专栏IT杂记

Mapreduce程序中reduce的Iterable参数迭代出是同一个对象

今天在对reduce的参数Iterable进行迭代时,发现一个问题,即Iterator的next()方法每次返回的是同一个对象,next()只是修改了Writa...

1935
来自专栏Python爱好者

判断是否为小米MIUI系统

16912
来自专栏吴伟祥

自定义template(Settings-->Live Templates)

psvm=public static void main(String[] args) {}

852
来自专栏运维技术迷

MySQL数据库(三):数据类型

安装环境: 操作系统版本:RHEL 6.5 版本:MYSQL 5.5 常见的信息种类: 数值型:一般用于体重、身高、成绩、工资 字符型:一般用于...

3635
来自专栏机器学习原理

图数据库neo4j介绍(3)——CypherCreateMatchSetDELETE REMOVE

Match (n:Person {id:'baba'}) set n.name='张三',n.age=50 return n

682
来自专栏测试开发架构之路

总结了一些指针易出错的常见问题(五)

指针与链表及其操作 //结构体定义 typedef struct _person{ char* firstname; char* lastna...

2695
来自专栏CodingToDie

MySql Hash 索引

Hash 索引结构的特殊性,其检索效率非常高,索引的检索可以一次定位,不像B-Tree 索引需要从根节点到枝节点,最后才能访问到页节点这样多次的IO访问,所以 ...

2733

扫码关注云+社区