【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是不允许给已有类通过分类添加属性的,因为类分类是不会自动生成成员变量的.但是,我们可以通过运行时机制就可以做到了. 本篇文章适 ...
随机推荐
- 关于javascript模块加载技术的一些思考
前不久有个网友问我在前端使用requireJs和seajs的问题,我当时问他你们公司以前有没有自己编写的javascript库,或者javascript框架,他的回答是什么都没有,他只是听说像requ ...
- 面向对象架构模式之:领域模型(Domain Model)
一:面向对象设计中最简单的部分与最难的部分 如果说事务脚本是 面向过程 的,那么领域模型就是 面向对象 的.面向对象的一个很重要的点就是:“把事情交给最适合的类去做”,即:“你得在一个个领域类之间跳转 ...
- 不插网线,看不到IP的解决办法
在Windows中,如果不插网线,就看不到IP地址,即使这个块网卡已经绑定了固定IP,原因是操作系统开启了DHCP Media Sense功能,该功能的作用如下: 在一台使用 TCP/IP 的基于 W ...
- 解决SQLSERVER数据库表被琐死!
) ) BEGIN Exec (@spId) FETCH NEXT FROM TmpCursor INTO @spId END CLOSE TmpCursor DEALLO ...
- [stm32] 一个简单的stm32vet6驱动2.4寸240X320的8位并口tft屏DEMO
书接上文: 最近在研究用低速.低RAM的单片机来驱动小LCD或TFT彩屏实现动画效果 首先我用一个16MHz晶振的m0内核的8位单片机nRF51822尝试驱动一个1.77寸的4线SPI屏(128X16 ...
- [源码]NumberToUpper 数字转中文
使用时需开启unsafe选项 构造函数有4个参数 number : 数字文本 isSimplified : 是否只使用简体中文,默认:false isMoney : 是否是金额模式(忽略小数点后3位, ...
- UWP入门教程1——UWP的前世今生
目录 引言 设备族群 UI 和通用输入模式 通用控件和布局面板 工具 自适应扩展 通用输入处理 引言 在本篇文章中,可以掌握以下知识: 设备族群,如何决定目标设备 新的UI控件和新面板帮助你适应不同的 ...
- 扩展GridView控件——为内容项添加拖放及分组功能
引言 相信大家对GridView都不陌生,是非常有用的控件,用于平铺有序的显示多个内容项.打开任何WinRT应用或者是微软合作商的网站,都会在APP中发现GridView的使用.“Tiles”提供了一 ...
- java ExecutorService
ExecutorService 通常Executor对象会创建并管理一组执行Runnable对象的线程,这组线程被称为线程池,Executor基于生产者-消费者模式.提交任务的执行者是生产者(产生待完 ...
- MVVM架构~knockoutjs系列之验证信息自定义输出~续
返回目录 上一讲中,我以一个实际中的例子说明了knockoutjs的自定义验证功能,在使用过程中,出现了一个问题,当然了不是问题,只是一种需求,上一讲中自定义验证的表现是:当页面加载后,自动显示有问题 ...