【OC底层】AssociatedObject 关联对象
如何实现给分类“添加成员变量”?
- 默认情况下,因为分类底层结构的限制,不能添加成员变量到分类中。但可以通过关联对象来间接实现
- 关联对象提供了以下API
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)
key的常见用法

objc_AssociationPolicy修饰符

给分类添加属性实例
假如已经有一个 XGPerson的类,现在我们需要扩展这个类,并且添加一个 age 属性
#import "XGPerson.h" // 分类属性是不会生成 get\set 方法的,如果不重写这两个方法,就无法正常使用属性
@interface XGPerson (Test) @property (nonatomic,assign) int age; @end
#import "XGPerson+Test.h"
#import <objc/runtime.h> @implementation XGPerson (Test) - (void)setAge:(int)age{ // @selector(age) 这个参数只要传一个地址指针就可以
objc_setAssociatedObject(self, @selector(age), @(age), OBJC_ASSOCIATION_ASSIGN);
} - (int)age{ // 隐式参数
// _cmd = @selectior(age)
return [objc_getAssociatedObject(self, _cmd) intValue];
}
调用:
XGPerson* p1 = [[XGPerson alloc]init];
p1.name = @"p1";
p1.age = ; XGPerson* p2 = [[XGPerson alloc]init];
p2.name = @"p2";
p2.age = ; NSLog(@"p1Name:%@ p1Age:%i----p2Name:%@ p2Age:%i",p1.name,p1.age,p2.name,p2.age);
输出:
-- ::38.666084+ 关联对象(增加分类属性)[:] p1Name:p1 p1Age:----p2Name:p2 p2Age:
关联对象的原理
- 实现关联对象技术的核心对象有
AssociationsManager
AssociationsHashMap
ObjectAssociationMap
ObjcAssociation
- objc4源码解读:objc-references.mm

- 关联对象存储结构图

- 关联对象并不是存储在被关联对象本身内存中
- 关联对象存储在全局的统一的一个AssociationsManager中
- 设置关联对象为nil,就相当于是移除关联对象
移除对象关联引用源码:
当一个对象触发 dealloc 时会调用下面的代码:

可以看出,在调用 dealloc 方法时,不需要我们手动去删除 对象关联信息,它会自己去调用 删除对象关联信息

【OC底层】AssociatedObject 关联对象的更多相关文章
- OC - runtime 之关联对象
header{font-size:1em;padding-top:1.5em;padding-bottom:1.5em} .markdown-body{overflow:hidden} .markdo ...
- AssociatedObject关联对象原理实现
介绍 关联对象(AssociatedObject)是Objective-C 2.0运行时的一个特性,允许开发者对已经存在的类在扩展中添加自定义的属性.在实际生产过程中,比较常用的方式是给分类(Cate ...
- Objective-C——关联对象
动态语言 OC是一种动态语言,它的方法,对象的类型都是到运行的时候才能够确定的.所以这就使得OC存在了关联对象这一强大的机制. 关联对象 所谓关联对象,其实就是我们在运行时对一个已存在的对象上面绑定一 ...
- 使用关联对象(AssociatedObject)为UIButton添加Block响应
在开发中,要给UIButton添加点击事件的话,通常的做法是这样的 UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem]; [ ...
- 关联对象 AssociatedObject 完全解析
我们在 iOS 开发中经常需要使用分类(Category),为已经存在的类添加属性的需求,但是使用 @property 并不能在分类中正确创建实例变量和存取方法. 不过,通过 Objective-C ...
- Runtime之成员变量&属性&关联对象
上篇介绍了Runtime类和对象的相关知识点,在4.5和4.6小节,也介绍了成员变量和属性的一些方法应用.本篇将讨论实现细节的相关内容. 在讨论之前,我们先来介绍一个很冷僻但又很有用的一个关键字:@e ...
- Runtime - Associated Objects (关联对象) 的实现原理
主要围绕3个方面说明runtime-Associated Objects (关联对象) 1. 使用场景 2.如何使用 3.底层实现 3.1 实现原理 3.2 关联对象被存储在什么地方,是不是存放在被 ...
- iOS Category 添加属性实现原理 - 关联对象
iOS Category 添加属性实现原理 - 关联对象 RunTime为Category动态关联对象 使用RunTime给系统的类添加属性,首先需要了解对象与属性的关系.对象一开始初始化的时候其属性 ...
- Runtime - 关联对象使用方法及注意点
大家都知道在分类里,可以间接的添加属性,运用runtime关联对象. 如下图,只是声明了btnClickedCount的set, get方法而已 并没有生成_btnClickedCount 成员变量, ...
随机推荐
- intellij idea elixir 插件
intellij-elixir https://github.com/KronicDeth/intellij-elixir
- CentOS7系列--1.3CentOS7用户管理
CentOS7用户管理 1. 添加用户 [root@centos7 ~]# useradd jack [root@centos7 ~]# passwd jack Changing password f ...
- ASP.Net与JSP如何共享Session值
思路: ASP.NET中序列化Session以二进制数据保存到数据库,然后由JSP读取数据库中的二进制数据反序列化成Session对象,再强制转化成JAVA的Session对象登录的ASPX文件 ...
- 润乾在jetty应用服务器下的JNDI配置一
一. 此处绑定的数据源是以 DBCP 为实现.首先必须将数据库驱动(这里用了MYSQL数据库)和DBCP所需要的 Jar 包复制到 Jetty 根目录的 lib 目录下.DBCP主要需要以下3个 ...
- CSS 实例之文字的凸起与凹陷
一些页面会有一些凹凸文字效果,这个主要是设置背景+文字阴影来达成这个效果的.文字阴影使用方法如下: text-shadow: 水平位置 垂直位置 模糊距离 阴影颜色 具体代码如下: body { ba ...
- SQLSERVER中KeyHashValue的作用(下)
SQLSERVER中KeyHashValue的作用(下) 昨天中午跟高文佳童鞋讨论了KeyHashValue的作用,到最后还是没有讨论出结果 昨天晚上德国的兄弟傅文伟做了一下实验,将实验结果交给我 感 ...
- [WSUS] [Windows 10 Upgrade 1607/1703] 升级出错,出现 0xC1800118 或者卡在下载中…… 0%后失败
1. 安装 KB3159706 ,并进行安装后维护操作:https://support.microsoft.com/en-us/help/3159706/update-enables-esd-decr ...
- .net验证是否合法邮箱和ip地址的方式
通常情况下第一时间会想到使用正则表达式去验证,但由于正则表达式过于复杂或者没有考虑到某些情况,从而导致问题或者判断的效率低.下面通过另一种方式去判断. 判断是否合法邮箱: /// <summar ...
- C#.NET里面抽象类,接口,虚方法
1抽象类 (1) 抽象方法只作声明,而不包含实现,可以看成是没有实现体的虚方法 (2) 抽象类不能被实例化 (3) 抽象类可以但不是必须有抽象属性和抽象方法,但是一旦有了抽象方法,就一定要把这个类声明 ...
- IP地址分类及CIDR划分方法
IP地址的分类和表示有三种形式,1.分类的IP地址.2.子网划分.3.无分类编址CIDR 1.分类的IP地址 IP地址:: = {<网络号>,<主机号>} 不同的网络号和主机号 ...