关联

关联是指把两个对象相互关联起来,使得其中的一个对象作为另外一个对象的一部分。
    关联特性只有在Mac OS X V10.6以及以后的版本上才是可用的。

在类的定义之外为类增加额外的存储空间

使用关联,我们可以不用修改类的定义而为其对象增加存储空间。这在我们无法访问到类的源码的时候或者是考虑到二进制兼容性的时候是非常有用。
    关联是基于关键字的,因此,我们可以为任何对象增加任意多的关联,每个都使用不同的关键字即可。关联是可以保证被关联的对象在关联对象的整个生命周期都是可用的(在垃圾自动回收环境下也不会导致资源不可回收)。

创建关联

创建关联要使用到Objective-C的运行时函数:objc_setAssociatedObject来把一个对象与另外一个对象进行关联。该函数需要四个参数:源对象,关键字,关联的对象和一个关联策略。当然,此处的关键字和关联策略是需要进一步讨论的。
  ■  关键字是一个void类型的指针。每一个关联的关键字必须是唯一的。通常都是会采用静态变量来作为关键字。
  ■  关联策略表明了相关的对象是通过赋值,保留引用还是复制的方式进行关联的;还有这种关联是原子的还是非原子的。这里的关联策略和声明属性时的很类似。这种关联策略是通过使用预先定义好的常量来表示的。
    下面的代码展示了如何把一个字符串关联到一个数组上。

static char overviewKey;
NSArray * array =[[NSArray alloc] initWidthObjects:@"One", @"Two", @"Three", nil];
//为了演示的目的,这里使用initWithFormat:来确保字符串可以被销毁
NSString * overview = [[NSString alloc] initWithFormat:@"@",@"First three numbers"];
objc_setAssociatedObject(array, &overviewKey, overview, OBJC_ASSOCIATION_RETAIN); [overview release];
//(1) overview仍然是可用的 [array release];
//(2)overview 不可用

   在(1)处,字符串overview仍然是可用的,这是因为OBJC_ASSOCIATION_RETAIN策略指明了数组要保有相关的对象。当数组array被销毁的时候,也就是在(2)处overview也就会被释放,因此而被销毁。如果此时还想使用overview,例如想通过log来输出overview的值,则会出现运行时异常。

获取相关联的对象

获取相关联的对象时使用Objective-C函数objc_getAssociatedObject。接着上面列表7-1的代码,我们可以使用如下代码来获取与array相关联的字符串:

NSString * associatedObject = (NSString *)objc_getAssociatedObject(array, &oveviewKey);

  

断开关联

断开关联是使用objc_setAssociatedObject函数,传入nil值即可。
    接着列表7-1中的程序,我们可以使用如下的代码来断开字符串overview和arry之间的关联:

objc_setAssociatedObject(array, &overviewKey, nil, OBJC_ASSOCIATION_ASSIGN);

   其中,被关联的对象为nil,此时关联策略也就无关紧要了。
    使用函数objc_removeAssociatedObjects可以断开所有关联。通常情况下不建议使用这个函数,因为他会断开所有关联。只有在需要把对象恢复到“原始状态”的时候才会使用这个函数。

一个完整的实例程序

下面的程序综合了前面的代码.

#import <Foundation/Foundation.h>
#import <objc/runtime.h> int main(int argc, const char* argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool] alloc init]; static char overviewKey;
NSArray *array =[[NSArray alloc] initWidthObjects:@"One", @"Two", @"Three", nil];
//为了演示的目的,这里使用initWithFormat:来确保字符串可以被销毁
NSString * overview = [[NSString alloc] initWithFormat:@"@",@"First three numbers"];
objc_setAssociatedObject(array, &overviewKey, overview, OBJC_ASSOCIATION_RETAIN);
[overview release]; NSString *associatedObject = (NSString *)objc_getAssociatedObject(arrray, &overviewKey);
NSLog(@"associatedObject:%@", associatedObject); objc_setAssociatedObject(array, &overviewKey, nil, OBJC_ASSOCIATION_ASSIGN);
[array release]; [pool drain];
return 0;
}

  

[Objective-C]关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)的更多相关文章

  1. Objective-C中的关联(objc_setAssociatedObject,objc_getAssociatedObject,objc_removeAssociatedObjects)

    关联的概念 所谓的关联,字面意思是把两个相关的对象放在一起,实际也是如此.把两个对象相互关联起来,使得其中的一个对象成为另外一个对象的一部分,这就是关联. 关联的作用 使用Category,我们可以给 ...

  2. category使用 objc_setAssociatedObject/objc_getAssociatedObject 实现添加属性

    属性 其实就是get/set 方法.我们可以使用  objc_setAssociatedObject/objc_getAssociatedObject  实现 动态向类中添加 方法 @interfac ...

  3. [Objective-C]关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)(转)

    转载自:http://blog.csdn.net/onlyou930/article/details/9299169 分类: Objective-C2013-07-11 11:54 3420人阅读 评 ...

  4. iOS - Objective-C 关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)

    关联是指把两个对象相互关联起来,使得其中的一个对象作为另外一个对象的一部分. 关联特性只有在Mac OS X V10.6以及以后的版本上才是可用的. 在类的定义之外为类增加额外的存储空间 使用关联,我 ...

  5. 关联:objc_getAssociatedObject和objc_setAssociatedObject使用

    为UIButton的category添加属性 UIButton+subTitle.h #import <UIKit/UIKit.h> #import <objc/runtime.h& ...

  6. 对象关联(associated objects)

    category与associative作为objective-c的扩展机制的两个特性,category即类型,可以通过它来扩展方法:associative,可以通过它来扩展属性:在iOS开发中,可能 ...

  7. iOS开发--Runtime的简单使用之关联对象

    一.Runtime关联对象的方法简介: 在<objc/runtime.h>中,有三个关联的方法,分别是: objc_setAssociatedObject objc_getAssociat ...

  8. 关于Kingfisher--备用

    序言--感谢好心大神分享 Kingfisher 是由 @onevcat 编写的用于下载和缓存网络图片的轻量级Swift工具库,其中涉及到了包括GCD.Swift高级语法.缓存.硬盘读写.网络编程.图像 ...

  9. iOS之 Category 属性 的理解

    在 Objective-C 中可以通过 Category 给一个现有的类添加属性,但是却不能添加实例变量 反正读第一遍的时候我是有点晕的,可以添加“属性”,然后又说“添加实例变量”,第一感觉就好像 有 ...

随机推荐

  1. JavaScript操作Cookie

    在Web开发中,我们经常使用Cookie保存一些不是非常敏高的数据.比如“下次自动登录”,“广告显示”等功能.定义是:某些网站为了辨别用户身份而存储在用户本地终端(主要是浏览器)上的数据.定义域RFC ...

  2. Util应用程序框架公共操作类(九):Lambda表达式扩展

    上一篇对Lambda表达式公共操作类进行了一些增强,本篇使用扩展方法对Lambda表达式进行扩展. 修改Util项目的Extensions.Expression.cs文件,代码如下. using Sy ...

  3. java多线程--信号量Semaphore的使用

    Semaphore可以控制某个共享资源可被同时访问的次数,即可以维护当前访问某一共享资源的线程个数,并提供了同步机制.例如控制某一个文件允许的并发访问的数量. 例如网吧里有100台机器,那么最多只能提 ...

  4. T4 模板自动生成带注释的实体类文件 - 只需要一个 SqlSugar.dll

    生成实体就是这么简单,只要建一个T4文件和 文件夹里面放一个DLL. 使用T4模板教程 步骤1 创建T4模板 ,一定要自已新建,把T4代码复制进去,好多人因为用我现成的T4报错(原因不明) 点击添加文 ...

  5. Vagrant入门

    简单地说,Vagrant让我们可以通过代码的方式快速地.可重复地创建针对不同虚拟环境的虚拟机,包括Virtualbox.AWS.Docker等.它使得我们可以一次性地.自动创建多个环境相同的虚拟机,对 ...

  6. openfire 初始密码

    openfire 初始密码 mssql2014 进入数据库,找到 ofUser 表 ,将密码字段对应的密文替换为下面的内容,则密码就是 admin ecbd03623cd819c48718db1b27 ...

  7. Rafy 领域实体框架演示(3) - 快速使用 C/S 架构部署

    本系列演示如何使用 Rafy 领域实体框架快速转换一个传统的三层应用程序,并展示转换完成后,Rafy 带来的新功能. <福利到!Rafy(原OEA)领域实体框架 2.22.2067 发布!> ...

  8. 记一个简单的sql查询

    在我们做各类统计和各类报表的时候,会有各种各样的查询要求.条件 这篇主要记录一个常见的统计查询 要求如下: 统计一段时间内,每天注册人数,如果某天没有人注册则显示为0 现在建个简单的表来试试 建表语句 ...

  9. web.config配置

    <appSettings> <add key="DepartmentRootID" value="A90AEAEC-E3D4-43DE-BB67-854 ...

  10. [无聊的事-连载之连开100个VS] 折腾你的骚机吧,骚年们!!!

    [无聊的事-连载之连开100个VS] 折腾你的骚机吧,骚年们!!! 只有8G内存的,用这个:打开你的CMD命令提示符如果只装了Visual Studio 2010,用这条命令,打开50个VSfor / ...