【iOS】关联属性存取数据
有时候我们需要在现有的类存放一些额外的信息,通常的做法是继承一个子类,然后定义新增加的属性,然而如果我们为每个需要的类都添加一个类显得太麻烦了,objc提供了一个关联属性的特性,可以给一个对象关联一个属性(做过.NET的朋友一定熟悉附加属性,objc的关联属性与.NET的附加属性有点类似类似)
使用关联属性很简单,下面是几个主要的函数
//设置关联属性
objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) //获取关联属性
id result = objc_getAssociatedObject(id object, const void *key) //删除所有附加属性
objc_removeAssociatedObjects(id object)
我们声明属性的时候会声明:copy,retain,assign 内存管理方式,在设置关联属性的时候也有,即 objc_setAssociatedObject 的第四个参数
| 关联类型 | 等效@property属性 |
|
OBJC_ASSOCIATION_ASSIGN |
assign |
|
OBJC_ASSOCIATION_RETAIN_NONATOMIC |
nonatomic, retain |
|
OBJC_ASSOCIATION_COPY_NONATOMIC |
nonatomic, copy |
|
OBJC_ASSOCIATION_RETAIN |
retain |
|
OBJC_ASSOCIATION_COPY |
copy |
关联属性的附加相当于NSDictionary,通过键值对存储,但是有一点跟NSDictionary不一样的是,设置关联对象所用的键(key)是不透明指针(opaque pointer),NSDictionary判断两个Key的isEqual方法判断是否相等,而关联对象只判断两个key的地址是否相等,而不会比较对象具体的值
看看下面例子
NSString *key1 = @"aaa";
NSString *key2 = [NSString stringWithFormat:@"aaa"];
NSString *key3 = @"bbb"; NSObject *obj = [[NSObject alloc] init]; objc_setAssociatedObject(obj, key1.UTF8String, @"aaa1", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(obj, key2.UTF8String, @"aaa2", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(obj, key3.UTF8String, @"bbb", OBJC_ASSOCIATION_RETAIN_NONATOMIC); id value1 = objc_getAssociatedObject(obj, key1.UTF8String);
id value2 = objc_getAssociatedObject(obj, key2.UTF8String);
id value3 = objc_getAssociatedObject(obj, key3.UTF8String); NSLog(@"value1 = %@", value1);
NSLog(@"value2 = %@", value2);
NSLog(@"value3 = %@", value3);
输出

这里的key1和key2都是@"aaa",但是取出来的value1和value2却不一样,这是因为key1和key2的地址不一样,在匹配的时候关联对象视为不同的key,所以通常我们在定义关联对象的key的时候使用静态全局变量作为键,这样可以保证地址一致
static char *key = "aaa";
NSObject *obj = [[NSObject alloc] init]; objc_setAssociatedObject(obj, key, @"aaa1", OBJC_ASSOCIATION_RETAIN_NONATOMIC);
objc_setAssociatedObject(obj, key, @"aaa2", OBJC_ASSOCIATION_RETAIN_NONATOMIC); id value1 = objc_getAssociatedObject(obj, key);
//把原有的值覆盖
id value2 = objc_getAssociatedObject(obj, key); NSLog(@"value1 = %@", value1);
NSLog(@"value2 = %@", value2);
参考文章:
《Effective Objective C 2.0》编写高质量iOS与OS X代码的52个有效方法 第10条
【iOS】关联属性存取数据的更多相关文章
- iOS之Category关联属性
Objective-C /** 原文件 */ // Person.h #import <Foundation/Foundation.h> @interface Person : NSObj ...
- Entity Framework关联查询以及数据加载(延迟加载,预加载)
数据加载分为延迟加载和预加载 EF的关联实体加载有三种方式:Lazy Loading,Eager Loading,Explicit Loading,其中Lazy Loading和Explicit Lo ...
- 李洪强iOS开发-网络新闻获取数据思路回顾
李洪强iOS开发-网络新闻获取数据思路回顾 01 创建一个继承自AFHTTPSessionManager的工具类:LHQNetworkTool 用来发送网络请求获取数据 1.1 定义类方法返回单例对 ...
- EF自动生成的(T4模板) 关联属性元数据修改
为了实现 T4模板关联属性 不要序列化的问题 就是要在具体的 关联属性上面添加一个元数据 这里利用以前的 Newtonsoft.Json 这个框架为例 效果应该为 就是要在关联属性上面添加元数据 [ ...
- hugegraph 数据存取数据解析
hugegraph 是百度开源的图数据库,支持hbase,mysql,rocksdb等作为存储后端.本文以EDGE 存储,hbase为存储后端,来探索是如何hugegraph是如何存取数据的. 存数据 ...
- EF如何操作内存中的数据以及加载相关联表的数据:延迟加载、贪婪加载、显示加载
之前的EF Code First系列讲了那么多如何配置实体和数据库表的关系,显然配置只是辅助,使用EF操作数据库才是每天开发中都需要用的,这个系列讲讲如何使用EF操作数据库.老版本的EF主要是通过Ob ...
- iOS开发网络篇—数据缓存
iOS开发网络篇—数据缓存 一.关于同一个URL的多次请求 有时候,对同一个URL请求多次,返回的数据可能都是一样的,比如服务器上的某张图片,无论下载多少次,返回的数据都是一样的. 上面的情况会造 ...
- WPF/Silverlight深度解决方案:(一)解锁被Storyboard束缚的关联属性
原文 WPF/Silverlight深度解决方案:(一)解锁被Storyboard束缚的关联属性 如果您在使用WPF/Silverlight进行相关动画开发中使用了Storyboard,并对关联属性进 ...
- runtime关联属性示例
前言 在开发中经常需要给已有的类添加方法和属性,但是Objective-C是不允许给已有类通过分类添加属性的,因为类分类是不会自动生成成员变量的.但是,我们可以通过运行时机制就可以做到了. 本篇文章适 ...
随机推荐
- js跨浏览器的事件处理函数
/* 跨浏览器的事件处理函数 */ var EventUtil = { addHandler : function(element,type,handler){ if(element.addEvent ...
- 换个角度理解云计算之HDFS
学习云计算,必然得了解Hadoop,而Hadoop中的HDFS(分布式文件系统)是一个基础,接下来就写一下我所理解的HDFS. 有一个很有特别的村庄,村庄里面有一个很牛逼的人,叫做“大哥”,村民们都信 ...
- Azure China (9) 在Azure China配置CDN服务
<Windows Azure Platform 系列文章目录> 本文介绍的是国内由世纪互联运维的Azure China Update 2015-11-20:Azure China CDN服 ...
- RSS与公众号
这次怀念下曾经火热的RSS.RSS是我很喜欢的一种看信息学习的方式,但是这项技术随着谷歌reader产品的停止已经陨落了.之后再无给力的客户端,无法让人愉悦的使用.我也曾尝试用鲜果,有道等国内产品,由 ...
- jQuery.fn.extend(object) object中this的指向
看到下面的代码后,一下子懵逼了.这个this指向哪儿去了. jQuery.fn.extend({ check: function() { return this.each(function() { t ...
- Jsp+ Servlet+Ajax实现点赞功能
1.jsp页面,使用ajax实现局部刷新 2.servlet接受处理去更新数据库 随后上传
- 我心中的核心组件(可插拔的AOP)~第二回 缓存拦截器
回到目录 AOP面向切面的编程,也称面向方面的编程,我更青睐于前面的叫法,将一个大系统切成多个独立的部分,而这个独立的部分又可以方便的插拔在其它领域的系统之中,这种编程的方式我们叫它面向切面,而这些独 ...
- HTML5 的 localStorage(本地数据库) 的用法
判断浏览器是否支持localStorage可以使用下面的代码:if(window.localStorage){ alert("支持localStorage") }else{ ...
- 【WP 8.1开发】解决调用真实摄像头会死机的问题
无论你是用Silverlight还是用RT的API来开发,在使用MediaCapture拍照片或录视频时,要是在模拟器上运行会万事大吉:但是,一旦放到真实手机上运行,肯定有人发现了,细心的朋友肯定发现 ...
- 编译原理(简单自动词法分析器LEX)
编译原理(简单自动词法分析器LEX)源程序下载地址: http://files.cnblogs.com/files/hujunzheng/%E6%B1%87%E7%BC%96%E5%8E%9F%E7 ...