Objective-C中的关联(objc_setAssociatedObject,objc_getAssociatedObject,objc_removeAssociatedObjects)
关联的概念
所谓的关联,字面意思是把两个相关的对象放在一起,实际也是如此。把两个对象相互关联起来,使得其中的一个对象成为另外一个对象的一部分,这就是关联。
关联的作用
使用Category,我们可以给一个类增加方法,而不用修改类文件本身。使用关联,我们就可以在类之外为类增加额外的存储空间,跟使用Category一样,不需要修改类文件本身。关联是基于关键字的,因此,我们可以为任何对象增加任意多的关联,每个关联都使用不同的关键字即可。关联是可以保证被关联的对象在关联对象的整个生命周期都是可用的(在垃圾自动回收环境下也不会导致资源不可回收)。
关联的创建
创建关联需要使用Objc的运行时函数:objc_setAssociatedOjbect来把一个对象和另外一个对象进行关联,所以需要导入头文件<objc/runtime.h>。该函数需要四个参数:源对象、关键字、关联的对象、关联策略。
关键字是一个void类型的指针。每一个关联的关键字必须是唯一的。通常都会采用静态变量来作为关键字。
关联策略表明了相关的对象是通过赋值、保留引用还是赋值的方式来进行关联的;还有这种关联是原子的还是非原子的。这里的关联策略和声明属性时的很类似。这种关联策略是通过预先定义好的常量来表示的。
下面的代码展示了如何把一个字符串关联到一个数组上。
static char overViewKey;
NSArray * array = [@[@"One",@"Two",@"Three"] retain];
NSString * overView = [[NSString alloc] initWithFormat:@"First three number"];
objc_setAssociatedObject(array, &overViewKey, overView, OBJC_ASSOCIATION_RETAIN);
[overView release];//(1) overView仍然是可用的
[array release]; //(2) overView不可用
在(1)处,字符串仍然是可用的,这是因为OBJC_ASSOCIATION_RETAIN策略指明了数组要持有相关的对象。当数组array被销毁的时候,也就是在(2)处,overView也就会被释放,因此而被销毁。如果此时还想使用overView,例如想通过NSLog来输出overView的值,则会出现异常。
获取相关的对象
获取相关的对象时使用Objc的函数obc_getAssociatedObject。
NSString * associatedOjbect = (NSString *)objc_getAssociatedObject(array, &overViewKey);
关联的断开
断开关联时使用objc_setAssociatedOjbect,传入nil值即可。如:
objc_setAssociatedObject(array, &overViewKey, nil, OBJC_ASSOCIATION_ASSIGN);
其中,被管理啊你的对象为nil,此时的关联策略也就无关紧要了。
使用函数objc_removeAssociatedOjbects可以断开所有的关联。通常情况下不建议使用这个函数,因为它会断开所有的关联。只有在需要把对象回复到原始状态的时候才会使用这个函数。
一个完整的示例程序
#import <Foundation/Foundation.h>
#import <objc/runtime.h> int main(int argc, const char * argv[])
{ @autoreleasepool { static char overviewKey;
NSArray * array = [@[@"One",@"Two",@"Three"] retain];
NSString * overview = [[NSString alloc] initWithString:@"First three nubmers"];
objc_setAssociatedObject(array, &overviewKey, overview, OBJC_ASSOCIATION_RETAIN);
[overview release]; NSString * associatedObject = (NSString *)objc_getAssociatedObject(array, &overviewKey);
NSLog(@"associatedObject:%@",associatedObject); objc_setAssociatedObject(array, &overviewKey, nil, OBJC_ASSOCIATION_ASSIGN); [array release]; }
return ;
}
来自:http://blog.csdn.net/onlyou930/article/details/9299169,略有修改
Objective-C中的关联(objc_setAssociatedObject,objc_getAssociatedObject,objc_removeAssociatedObjects)的更多相关文章
- objective-c 中的关联介绍
objective-c 中的关联介绍 转载请注明CSDN博客上的出处: http://blog.csdn.net/daiyibo123/article/details/46471993 如何设置关联 ...
- category使用 objc_setAssociatedObject/objc_getAssociatedObject 实现添加属性
属性 其实就是get/set 方法.我们可以使用 objc_setAssociatedObject/objc_getAssociatedObject 实现 动态向类中添加 方法 @interfac ...
- 理解Objective C 中id
什么是id,与void *的区别 id在Objective C中是一个类型,一个complier所认可的Objective C类型,跟void *是不一样的,比如一个 id userName, 和vo ...
- 浅谈Objective—C中的面向对象特性
Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...
- Django model中 双向关联问题,求帮助
Django model中 双向关联问题,求帮助 - 开源中国社区 Django model中 双向关联问题,求帮助
- 转:如何在 LoadRunner 脚本中做关联 (Correlation)
如何在 LoadRunner 脚本中做关联 (Correlation) 当录制脚本时,VuGen会拦截client端(浏览器)与server端(网站服务器)之间的对话,并且通通记录下来,产生脚本.在V ...
- 在Eclipse中如何关联源代码
我们就以Struts2框架为例,展示在Eclipse中如何关联源代码.例如,在Struts2框架的学习中,我们有时需要查看ActionSupport这个类的源码,这个时候就要在Eclipse中关联源代 ...
- TSQL:A表字段与B表中的关联,关联条件中一列是随机关联的实现方式
A表字段与B表中的关联,关联条件中一列是随机关联的实现方式 create table test( rsrp string, rsrq string, tkey string, distan strin ...
- objective C中的字符串NSStirng常用操作
objective C中的字符串操作 在OC中创建字符串时,一般不使用C的方法,因为C将字符串作为字符数组,所以在操作时会有很多不方便的地方,在Cocoa中NSString集成的一些方法,可以很方便的 ...
随机推荐
- JAVA快速功能
1.日期格式化 Date date=new Date(); //转换成时间格式12小时制 SimpleDateFormat df_12=new SimpleDateFormat("yyyy- ...
- Servlet 2.4 规范之第七篇:过滤器
过滤器是一套java组件,用于在请求—>资源—>应答的这一过程中即时转换处理负载和头信息. 本章讲述了Servlet 2.4 API中一些类和方法,这些类和方法提供了一套轻量级框架用于过滤 ...
- linux题目整理(二)
1.如何过滤出已知当前目录下oldboy中的所有一级目录(不包含子目录,即只能是一级目录) 方法1:find ./ -type d -maxdepth 1方法2:ls -F方法3:ls -l | g ...
- django rest framework如何实现nest field显示,如何保存有外键的字段更新
一步一步深入了. 相关设置技巧如下: 直接nest field显示: class VersionPoolSerializer(serializers.ModelSerializer): site_na ...
- CentOS 7.0 服务管理 – systemctl 命令
转载自:http://linux.it.net.cn/CentOS/fast/2014/0720/3212.html CentOS 7.0中已经没有service命令,而是启用了systemctl服务 ...
- Spring bean初始化以及管理
在完成bean实例化后,spring会根据配置文件的设定情况对bean 的属性进行初始化, 1.autowire方式 (可查找自动装配对象 但bean中要有相应属性的set方法)这是一个自动装配的机制 ...
- Systemd入门教程:命令篇(转)
作者: 阮一峰 日期: 2016年3月 7日 Systemd 是 Linux 系统工具,用来启动守护进程,已成为大多数发行版的标准配置. 本文介绍它的基本用法,分为上下两篇.今天介绍它的主要命令,下一 ...
- SQL SERVER 2012 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。 (System.Data)
标题: 连接到服务器------------------------------ 无法连接到 192.168.1.253. ------------------------------其他信息: 尝试 ...
- 输入法不能使用ctrl+shift进行切换的问题
第一种情况就是,你的输入法只有一种(而且这种输入法并不是“中文(简体) 微软拼音输入法”). 如果是只有一种输入法的话,是无法进行切换的,如果你是想要把输入法切换到无输入法状态,那么你可以通过设置任务 ...
- 几个有关Hadoop自带的性能测试工具的应用
http://www.talkwithtrend.com/Question/177983-1247453 一些测试的描述如下内容最为详细,供你参考: 测试对于验证系统的正确性.分析系统的性能来说非常重 ...