• 可以通过“关联对象”机制来把两个对象连起来
  • 定义关联对象时可指定内存管理语义,用以模仿定义属性时所采用的“拥有关系”与“非拥有关系”
  • 只有在其他做法不可行时才应选用关联对象,因为这种做法通常会引入难于查找的 bug

目的:需要在对象中存放相关信息,方法一,从对象所属的类中继承一个子类,然后改用这个子类对象。

  方法二:关联对象(Associated Object),对象通过“键”来区分。

可以把某对象想象成NSDictionary,把关联到对象上调用[object setObject:value forKey:key] 与 [object objectForKey:key]方法。但是设置关联对象那个时用的键(key)是个“不透明的指针“(opaque pointer),

如果在两个键上调用”isEqual“方法返回值是 YES, 那么NSDictionary就认为两者相等;然而设置关联对象时,二者必须是完全相同的指针才行。鉴于此,在设置关联对象值时,通常使用静态全局变量做键。

下列方法管理关联对象:

  void objc_setAssociatedObject (id object, void*key, id value, objc_AssociationPolicy policy)

  此方法以给定的键和策略为某对象设置关联对象值

   id objc_getAssociatedObject(id object, void*key)

   此方法根据给定的键从某对象中获取相应的关联对象值

  void objc_removeAssociatedObjects(id object)

  此方法移除指定对象的全部关联对象

例子:UIAlertView 类,警告信息,当用户按下按钮关闭该视图时,需要用委托协议(delegate protocol)在处理此动作,但是要想设置好这个委托机制,就得把创建警告视图和处理按钮动作的代码分开。比兔使用UIAlertView 时,一般都会这么写:

- (void)askUserAQuestion {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Question"
message:@"What do you want to do?"
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTiles:@"Continue",nil];
[alert show];
}
// UIAlertViewDelegate protocol method
- (void)alertView:(UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttoIndex == ) {
[self doCancel];
} else {
[self doContinue];
}
}

如果想在同一个类里处理多个警告信息视图,那么代码就会变得更为复杂,必须在delegate方法中检查传入的 alertView 参数

可以使用关联对象 在创建警告视图的时候直接把处理每个按钮的逻辑都写好:创建完警告视图之后,设定一个与之关联的“块” block,等到执行 delegate 方法是再将其读出来,代码如下

#import <objc/runtime.h>
static void *EOCMyAlertViewKey = "EOCMyAlertViewKey";
- (void)askUserAQuestion {
UIAlertView *alert = [[UIAlertViewalloc] initWithTitle:@"Question"
message:@"What do you want to do?"
delegate:self
cancelButtonTitle:@"Cancel"
otherButtonTitles:@"Continue", nil];
void (^block) (NSInteger) = ^(NSInteger buttonIndex) {
if (buttonIndex == ) {
[self doCancel];
} else {
[self doContinue];
}
};
objc_setAssociateObject(alert, EOCMyAlertViewKey, block, BJC_ASSOCIATION_COPY);
[alert show];
}
// UIAlertViewDelegate protocol method 关联类型等效的@property 属性为
- (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
void (^block) (NSInteger) = objc_getAssociateObject(alertView, EOCMyAlertViewKey);
block(buttonIndex);
}

注意:块可能要捕获 (capture)某些变量,这也许会造成“保留环)(retain cycle)

Effective Objective-C 2.0 — 第10条:在既有类中使用关联对象存放自定义数据的更多相关文章

  1. 【从0到1学Web前端】javascript中的ajax对象(一) 分类: JavaScript 2015-06-24 10:18 754人阅读 评论(1) 收藏

    现在最流行的获取后端的(浏览器从服务器)数据的方式就是通过Ajax了吧.今天就来详细的来学习下这个知识吧.如果使用ajax来访问后段的数据,浏览器和浏览器端的js做了那些工作呢?我做了一个图,请大家看 ...

  2. Effective Objective-C 2.0 — 第12条:理解消息转发机制

    11 条讲解了对象的消息传递机制 12条讲解对象在收到无法解读的消息之后会发生什么,就会启动“消息转发”(message forwarding)机制, 若对象无法响应某个选择子,则进入消息转发流程. ...

  3. Effective Objective-C 2.0 — 第9条:以“类族模式”隐藏实现细节

    第9条:以“类族模式”隐藏实现细节 类族模式可以把实现细节隐藏在一套简单的公共接口后面 系统框架中经常使用类族 从类族的公共抽象基类中继承子类时要当心,若有开发文档,则应首先阅读 “类族”(class ...

  4. C# 语言规范_版本5.0 (第10章 类)

    1. 类 类是一种数据结构,它可以包含数据成员(常量和字段).函数成员(方法.属性.事件.索引器.运算符.实例构造函数.静态构造函数和析构函数)以及嵌套类型.类类型支持继承,继承是一种机制,它使派生类 ...

  5. 10条PHP编程习惯助你找工作

    过去的几周对我来说是一段相当复杂的经历.我们公司进行了大裁员,我是其中之一,但却体验到了其中的乐 趣.我从来没有被开除过,所以很难不去想得太多.我开始浏览招聘板块,一个全职PHP程序员的职位很吸引人, ...

  6. Linux系统性能10条命令监控

    Linux系统性能10条命令监控 概述 通过执行以下命令,可以在1分钟内对系统资源使用情况有个大致的了解. uptime dmesg | tail vmstat 1 mpstat -P ALL 1 p ...

  7. 将Web应用性能提高十倍的10条建议

    导读 提高 web 应用的性能从来没有比现在更重要过.网络经济的比重一直在增长:全球经济超过 5% 的价值是在因特网上产生的(数据参见下面的资料).这个时刻在线的超连接世界意味着用户对其的期望值也处于 ...

  8. 转:10条建议让你创建更好的jQuery插件

    在开发过很多 jQuery 插件以后,我慢慢的摸索出了一套开发jQuery插件比较标准的结构和模式.这样我就可以 copy & paste 大部分的代码结构,只要专注最主要的逻辑代码就行了.使 ...

  9. Laxcus大数据管理系统2.0(10)- 第八章 安全

    第八章 安全 由于安全问题对大数据系统乃至当前社会的重要性,我们在Laxcus 2.0版本实现了全体系的安全管理策略.同时我们也考虑到系统的不同环节对安全管理的需求是不一样的,所以有选择地做了不同的安 ...

随机推荐

  1. 控制浏览器高度 宽度 只能支持ie

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"          "http://ww ...

  2. 我所经历的JS性能优化

    转自http://www.cnblogs.com/koking/archive/2011/10/17/2215665.html 折腾了好几天,纠结了好几天,郁闷了好几天,终于在今天可以释怀了,留下其中 ...

  3. camerc文件播放

    下载CamtasiaStudio 5中文版,打开CamtasiaStudio.exe在左边有生成选项,点左边工具框内添加/导入媒体,则选择下面的批量生成.弹出添加文件的菜单点添加文件,加入你要转换的c ...

  4. [模板]tarjan求强连通分量

    大约是今年4月学的算法了,后来5月的时候做题还写了一个退化的tarjanQAQ. 时间复杂度:O(n+m) 用途:有向图缩环 #include<set> #include<cmath ...

  5. js-自制轮播插件!

    刚接触轮播的时候,感觉这种东西好高端,后来学习了jquery后,发现原来挺简单的,而且实现轮播也有很多形式,我用jquery自制了一个轮播插件,其实我这个说是插件,好像其实就是一个高度抽象的函数而已. ...

  6. BZOJ1178 [Apio2009]CONVENTION会议中心

    本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转载请注明出处,侵权必究,保留最终解释权! Description Siruseri政府建造了 ...

  7. VisualSVN Server和Subversion的联系

    VisualSVN Server是只能在Windows平台上搭建的SVN服务器,内核使用的是Subversion,做了整合:apache+subversion+WMI(实现操作界面等). 用这个的好处 ...

  8. bios中只有windows boot manager下用U盘启动

    在重装系统的时候,很多时候都是先进入bios设置成U盘启动项,然后进行安装,如果年代久远一点的,就设置成光驱启动,再进行:随着时间的推行,光驱已经开始淘汰了,也怀念以前的光驱装机的时光!-:) 开始进 ...

  9. PriorityQueue

    基本概念 顾名思义,PriorityQueue是优先级队列,它首先实现了队列接口(Queue),与LinkedList类似,它的队列长度也没有限制,与一般队列的区别是,它有优先级的概念,每个元素都有优 ...

  10. CentOS关机

    1. 关机前准备 1.1 查看有谁在线 who 1.2 查看网络联机状态 netstat -a 1.3 查看后台正在执行的程序 ps -aux 1.4 向所有在线用户发出警告信息 shutdown - ...