Objective-C——关联对象
动态语言
OC是一种动态语言,它的方法,对象的类型都是到运行的时候才能够确定的。所以这就使得OC存在了关联对象这一强大的机制。
关联对象
所谓关联对象,其实就是我们在运行时对一个已存在的对象上面绑定一个对象,使两个对象变成动态的聚合关系。
关联对象和属性一样有着关键字,以下是关联对象的存储策略:
| 关联类型 | 等效的@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 |
关联对象主要靠下面三个函数,它们都位于<objc/runtime>下
void objc_setAssociatedObject(id object, void *key ,id value ,objc_AssociationPolicy policy)
设置关联对象
| 参数 | 说明 |
| object | 要进行关联的对象 |
| key | 一个内存表示,在比较两个关联对象是否相等时,比较的就是内存地址,所以一般用一个全局静态变量表示 |
| value | 被关联的对象 |
| policy | 存储策略 |
id objc_getAssociatedObject(id object, void *key)
获取关联对象
void objc_removeAssociatedObjects(id object)
删除关联对象
作用
关联对象一般用于动态的扩展一个对象,但是这一般都是在其他方法不行的事后才会使用,因为关联对象很可能会出现难以查找的bug。
关联对象有时也会用于在category向类添加属性,这点等会儿在分析。
下面Demo在UIAlertView上面动态绑定了一个block,把按钮处理逻辑和alert调用整合在了一起。
static char *AlertKey = "alertKey";
- (void)viewDidLoad {
[super viewDidLoad];
alert = [[UIAlertView alloc] initWithTitle:@"alert" message:@"message" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"other", nil];
}
- (IBAction)click:(id)sender {
void (^block) (NSInteger) = ^(NSInteger buttonIndex){
if (buttonIndex == ){
NSLog(@"click cancel");
}
else{
NSLog(@"click other");
}
};
objc_setAssociatedObject(alert, AlertKey, block, OBJC_ASSOCIATION_COPY);
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
void (^block)(NSInteger) = objc_getAssociatedObject(alertView, AlertKey);
block(buttonIndex);
}
运行程序点击两个按钮分别输出如下
-- ::27.146 Dynamic[:] click other
-- ::28.262 Dynamic[:] click cancel
接下来我们给UIViewController在category中添加一个addition属性
#import "ViewController.h"
#import <objc/runtime.h> @interface UIViewController (Addition) @property(nonatomic ,copy) NSString *addition; @end
#import "UIViewController+Addition.h"
static const void *IndieBandNameKey = &IndieBandNameKey;
@implementation UIViewController (Addition)
-(void)setAddition:(NSString *)addition{
objc_setAssociatedObject(self, IndieBandNameKey, addition, OBJC_ASSOCIATION_COPY);
}
-(NSString *)addition{
return objc_getAssociatedObject(self, IndieBandNameKey);
}
@end
这里说明一下,这里关联的实际上是形参addition,和属性没有什么关系,写@property 就是为了能够使用‘.’语法。但是@porperty里面的属性存储策略还是要和关联对象一致的,这样不容易造成误解。
所以每次setAddition实际上我们并不是修改了原有内存的值,而是改变了指针指向的地址,这里需要注意一下。
然后修改刚才alert的代码
- (void)viewDidLoad {
[super viewDidLoad];
alert = [[UIAlertView alloc] initWithTitle:@"alert" message:@"message" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"other", nil];
alert.delegate = self;
self.addition = @"addition";
}
- (IBAction)click:(id)sender {
void (^block) (NSInteger) = ^(NSInteger buttonIndex){
if (buttonIndex == ){
NSLog(@"click cancel");
objc_removeAssociatedObjects(self);
}
else{
NSLog(@"click other");
NSLog(@"%@",self.addition);
}
};
objc_setAssociatedObject(alert, AlertKey, block, OBJC_ASSOCIATION_COPY);
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
void (^block)(NSInteger) = objc_getAssociatedObject(alertView, AlertKey);
block(buttonIndex);
}
注意三条加粗的语句,然后我们运行看结果
-- ::54.353 Dynamic[:] click other
-- ::54.353 Dynamic[:] addition
-- ::55.804 Dynamic[:] click cancel
-- ::57.491 Dynamic[:] click other
-- ::57.491 Dynamic[:] (null)
首先我们使用了关联对象,所以点击other的时候会看到打印出了addition。点击cancel的时候又因为我们remove了关联对象,此时再点击other的时候addition就变成null了。
Objective-C——关联对象的更多相关文章
- Effective Objective-C 2.0 — 第10条:在既有类中使用关联对象存放自定义数据
可以通过“关联对象”机制来把两个对象连起来 定义关联对象时可指定内存管理语义,用以模仿定义属性时所采用的“拥有关系”与“非拥有关系” 只有在其他做法不可行时才应选用关联对象,因为这种做法通常会引入难于 ...
- ios 关联对象运用 objc_setAssociatedObject
点按钮的时候,给alertView添加一个关联对象(被点击这个按钮), objc_setAssociatedObject(alert, &kRepresentedObject, sender, ...
- 使用关联对象(AssociatedObject)为UIButton添加Block响应
在开发中,要给UIButton添加点击事件的话,通常的做法是这样的 UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem]; [ ...
- Mybatis之ResultMap一个简短的引论,关联对象
基础部分能够查看我的还有一篇博客http://blog.csdn.net/elim168/article/details/40622491 MyBatis中在查询进行select映射的时候.返回类型能 ...
- iOS开发--Runtime的简单使用之关联对象
一.Runtime关联对象的方法简介: 在<objc/runtime.h>中,有三个关联的方法,分别是: objc_setAssociatedObject objc_getAssociat ...
- 小解系列-自关联对象.Net MVC中 json序列化循环引用问题
自关联对象在实际开发中用的还是比较多,例如常见的树形菜单.本文是自己实际的一个小测试,可以解决循环引用对象的json序列化问题,文笔不好请多见谅,如有错误请指出,希望有更好的解决方案,一起进步. 构造 ...
- MyBatis之ResultMap简介,关联对象
MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap,resultType是直接表示返回类型的,而resultMap则是对外部ResultM ...
- hibernate关联对象的增删改查------查
本篇博客是之前博客hibernate关联对象的增删改查------查 的后继,本篇代码的设定都在前文已经写好,因此读这篇之前,请先移步上一篇博客 //代码片5 SessionFactory sessi ...
- obj-c编程19:关联对象
对于一些无法子类化的实例对象来说,如果希望将一个对象与其绑定该如何做呢? 以下示例虚构了一个HyConsoleAlert类,User类将会使用该类在控制台显示定制的告警.如果User中包括多个Aler ...
- Django ORM中,如何使用Count来关联对象的子集数量
示例models 解决方法 有时候,我们想要获取一个对象关联关系的数量,但是我们不要所有的关联对象,我们只想要符合规则的那些关联对象的数量. 示例models # models.py from dja ...
随机推荐
- Ajax_使用 jQuery 实现Ajax
[jQuery中的Ajax] 1.jQuery对Ajax操作进行了封装,在jQuery中最底层的方法时 $.ajax().第二层是 load() , $.get() 和 $.post(),第三层是 ...
- Java Web学习总结(29)——Java Web中的Filter和Interceptor比较
1. 背景 在设计web应用的时候,用户登录/注册是必不可少的功能,对用户登录信息进行验证的方法也是多种多样,大致可以认为如下模式:前端验证+后台验证.根据笔者的经验,一般会在前端进行一些例如是否输入 ...
- Why does MySQL produce so many temporary MYD files?
http://dba.stackexchange.com/questions/30505/why-does-mysql-produce-so-many-temporary-myd-files Data ...
- hdu poj KMP简单题目总结
hdu 3336 题意:输入一个字符串求每个前缀在串中出现的次数和 sol:只要稍微理解下next 数组的含义就知道只要把每个有意义的next值得个数加起来即可 PS:网上有dp解法orz,dp[i] ...
- noip模拟赛 运
[问题背景]zhx 和妹子们玩数数游戏.[问题描述]仅包含 4 或 7 的数被称为幸运数.一个序列的子序列被定义为从序列中删去若干个数, 剩下的数组成的新序列.两个子序列被定义为不同的当且仅当其中的元 ...
- zoj 3812 状压dp
转载:http://blog.csdn.net/qian99/article/details/39138329 题意:给出n个物品,每个物品有两种属性Wi,Ti,有q组查询,每组查询要求在n个物品中选 ...
- Ubuntu下非常规方法安装绿色软件(压缩包)
继上一篇http://www.cnblogs.com/EasonJim/p/7117567.html文章中说的常规方式安装的软件,都会自动在命令行及Dash Home中体现. 但是如果是使用压缩包进行 ...
- CentOS 7: Install vsftpd
Install vsftpd All commands should be run with ‘root’ user. Run the following command in terminal to ...
- access-list/eigrp等 反掩码计算
access-list/eigrp等 反掩码计算 原则:地址部分,相同的照写,不同的写"0" 反掩码部分,相同的写"0",不同的写"1&quo ...
- Leetcode题解(5):L58/Length of Last Word
L58: Length of Last Word Given a string s consists of upper/lower-case alphabets and empty space cha ...