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

    mvn archetype:create :创建 Maven 项目 mvn compile :编译源代码 mvn deploy 发布项目 mvn test-compile :编译测试代码 mvn te ...

  2. HTML常用标签与表格标签

    超链接标签: <a href="超链接地址" target="_blank">超链接的文字</a> _blank或new是在新网页中打开 ...

  3. ThreadLocal详解(实现多线程同步访问变量)

    ThreadLocal翻译成中文比较准确的叫法应该是:线程局部变量. 这个玩意有什么用处,或者说为什么要有这么一个东东?先解释一下,在并发编程的时候,成员变量如果不做任何处理其实是线程不安全的,各个线 ...

  4. datatable绑定comboBox显示数据[C#]

    实现功能: datatable绑定comboBox,在下拉菜单中显示对应数据 实现方法: 1.生成datatable,并为combox绑定数据源: comboBox1.DataSource = dt1 ...

  5. Unity 移动端触摸屏操作

    Unity 触屏操作 当将Unity游戏运行到IOS或Android设备上时,桌面系统的鼠标左键可以自动变为手机屏幕上的触屏操作,但如多点触屏等操作却是无法利用鼠标操作进行的.Unity的Input类 ...

  6. Spark Shell & Spark submit

    Spark 的 shell 是一个强大的交互式数据分析工具. 1. 搭建Spark 2. 两个目录下面有可执行文件: bin  包含spark-shell 和 spark-submit sbin 包含 ...

  7. Linux 简介

    转载:http://c.biancheng.net/cpp/html/2726.html Linux简介 严格的来讲,Linux 不算是一个操作系统,只是一个 Linux 系统中的内核,即计算机软件与 ...

  8. Leetcode 375. Guess Number Higher or Lower II

    We are playing the Guess Game. The game is as follows: I pick a number from 1 to n. You have to gues ...

  9. IIS配置错误信息输出

    Asp.net: 一.通过 IIS 配置 1.打开IIS管理器,或按住 WIN + R 打开命令行输入 inetmgr 打开 IIS 管理 2.左边目录选择目标站点,在右边 IIS 块中双击 “错误页 ...

  10. 再次深入探索datasource问题?

    datasource现在几乎每个web框架都会有集成,但是对于数据源的设计原理以及应用上,很少进行深入的研究:实际上数据源也是web框架的核心之一了解一下其内涵还是非常重要的. 数据源(Data So ...