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

    xmanager4.0注册吗 --

  2. Mysql将近两个月的记录合并为一行显示

    最近做报表统计,用到要求把近两个月的绩效作比较,并作出一些环比数据等. 场景:将1班同学的两个月的语文的平均成绩合并到一行比较. CREATE TABLE `Chinese_score` ( `id` ...

  3. Java多线程与并发库高级应用-工具类介绍

    java.util.concurrent.Lock 1.Lock比传统线程模型中的synchronized方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码片段要实现同步互 ...

  4. ubuntu16.04+cuda7.5

    0 安装了ubuntu16.04 GT980的显卡,安装了nvidia340的驱动 1 下载cuda7.5的.run文件 2 进入tty1,service stop lightdm 3 sudo sh ...

  5. 【bzoj1408】 Noi2002—Robot

    http://www.lydsy.com/JudgeOnline/problem.php?id=1408 (题目链接) 题意 定义了3种数,分别求这3种数的φ的和,其中φ(1)=0. Solution ...

  6. 遍历map集合

    for(var key in map){ if(data.hasOwnProperty(key)){ var value = map[key]; } }​

  7. 找女神要QQ号码

    引言 我们组来了个美女程序员,我心里窃喜,哈哈这下机会来了.我在想怎么下手呢?好吧,还是从QQ号码开始,找到女神要到QQ号,哈哈,我真是个天才~~~ 是这样子滴 想法是美好的,现实是残酷的,找女神要Q ...

  8. 重启电脑后,oracle数据库连接不上

    oracle10g安装成功后使用正常,重启电脑后,连接不上了,电脑-服务中各个服务都手动重启了,仍然无效 报错信息:ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务 要手工去操作命 ...

  9. Json对象与Json字符串互转(转载)

    一.jQuery插件支持的转换方式 1 $.paseJSON(jsonstr);//将json字符串转换为json对象 二.浏览器支持的转换方式(Firefox,Chrome,Opera,Safair ...

  10. Mysql数据库基本操作 (一)

    1.使用mysql数据库的必备要素 a. 安装MySQL服务端 b. 安装MySQL客户端 c. [客户端]连接[服务端] d. [客户端]发送命令给[服务端MySQL]服务的接受命令并执行相应操作( ...