关联

关联是指把两个对象相互关联起来,使得其中的一个对象作为另外一个对象的一部分。
    关联特性只有在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. Dijkstra算法优先队列实现与Bellman_Ford队列实现的理解

    /* Dijkstra算法用优先队列来实现,实现了每一条边最多遍历一次. 要知道,我们从队列头部找到的都是到 已经"建好树"的最短距离以及该节点编号, 并由该节点去更新 树根 到其 ...

  2. java 大数据处理类 BigDecimal 解析

    这两天,由于我的必修课概率论里经常要用到排列组合的计算,感觉很麻烦,加上现代智能手机的计算器是没有这方面功能的. 所以,就自己动手写了个安卓的 排列组合 计算器,用了一天,发现有很大的问题,阶乘达百亿 ...

  3. c 语言的位运算符复习

    转载和修正,原文连接:http://www.cnblogs.com/911/archive/2008/05/20/1203477.html 位运算是指按二进制进行的运算.在系统软件中,常常需要处理二进 ...

  4. Oracle在线重定义DBMS_REDEFINITION 普通表—>分区表

    实验环境:RHEL 6.4 + Oracle 11.2.0.3实验:在线重定义 普通表 为 分区表,包括主键对应的索引都改造为分区索引. 1,构造普通表t_objects conn test1/tes ...

  5. 重温Servlet学习笔记--session对象

    session的类型是属于HttpSession,HttpSession是由javaWeb提供的,用来会话跟踪的类.session是服务器端对象,保存在服务器端. HttpSession是servle ...

  6. 【JUC】JDK1.8源码分析之CountDownLatch(五)

    一.前言 分析完了CyclicBarrier后,下面分析CountDownLatch,CountDownLatch用于同步一个或多个任务,强制他们等待由其他任务执行的一组操作完成.CountDownL ...

  7. 浅解析js中的对象

    浅解析js中的对象 原文网址:http://www.cnblogs.com/foodoir/p/5971686.html,转载请注明出处. 前面的话: 说到对象,我首先想到的是每到过年过节见长辈的时候 ...

  8. 7.7 数据注解特性--Table

    大家可能注意到,有几个特性,我没有翻译,因为实在是太简单了,看一下就知道,之前也学过,现在只是系统学一下,所以就粗略的看一下就行了. 现在学习数据注解特性的--Table特性. Table 特性可以被 ...

  9. 【转】浅谈MVC与三层架构

    首先给大家引入下MVC的概念: MVC(Model View Controller)模型.视图以及控制器,它是一种较为广泛应用的结构设计模式. 模型:就是在MVC设计模式中需要被显示的数据.在通常情况 ...

  10. C#遍历文件夹下所有文件

    FolderForm.cs的代码如下: using System; using System.Collections.Generic; using System.Diagnostics; using ...