【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 成员变量, ...
随机推荐
- p2p状态码
因为需要的确定状态太多,减少数据库的压力,采取二进制表示状态码 状态码工具类 package com.xmg.p2p.base.util; /** * 用户状态类,记录用户在平台使用系统中所有的状态. ...
- VMware桥接模式下主机和和虚机间互相ping不通的处理方法
在 "编辑"->"虚拟网络编辑器" 里面的vmnet0 桥接模式 里面是自动连接,把他改为真实的物理网卡即可,如下图:
- IOT安全
相关资源 IOT 漏洞 top 10 https://xz.aliyun.com/t/2278 https://www.owasp.org/images/8/8e/Infographic-v1.jpg ...
- lodop 代码注释
LODOP.SET_PRINT_PAGESIZE(1,1000,1500,""); /*1,纵向输出;1000,宽度;1500,高度*:单位为0.1毫米/LODOP.ADD_PR ...
- 通过ES6实现的Ajax类
个人学习用途而已,仅供参考. class Ajax { constructor(xhr) { xhr = window.XMLHttpRequest ? new XMLHttpRequest() : ...
- python利用unittest进行测试用例执行的几种方式
利用python进行测试时,测试用例的加载方式有2种: 一种是通过unittest.main()来启动所需测试的测试模块: 一种是添加到testsuite集合中再加载所有的被测试对象,而tes ...
- Azure Cosmos DB 使用费用参考
之前在学习Cosmos DB 中SQL API(DocumentDB) 的时候,也就是之前做的一些笔记,看到有使用费用的一些介绍,就有兴趣的去了解了下,做了一下简单的总结. 想了解更多或是购买使用的还 ...
- UITextField使用的一些细节
UITextField使用的一些细节 这篇博文是我自己使用UITextField的一些总结,并没有太多营养,并会持续更新. 2014.9.15 ---------------------------- ...
- iOS手势处理
iOS手势处理 iOS手势有着如下几种: UITapGestureRecognizer UIPinchGestureRecognizer UIRotationGestureRecognizer UIS ...
- spine获取骨骼位置
time: 2015/07/23 版本: /****************************************************************************** ...