Runtime应用(二)使用对象关联为分类增加属性(每个对象的属性互不干扰)

一、对象的关联方法有

1、 void objc_setAssociatedObject(id object, const void *key, id value,objc_AssociationPolicy policy) ,关联对象(将值value与对象object关联起来)

参数key:将来可以通过key取出这个存储的值

参数policy:存储策略(assign、copy、retain)

2、 id objc_getAssociatedObject(id object, const void *key) ,利用参数key将对象中存储的对应值取出

二、利用分类为每个对象添加属性(可作为对象的标签或存储信息)

声明代码:

@interface NSObject (CX)
/**
 *  为每一个对象添加一个name属性
 */
@property (nonatomic,copy) NSString *name;
/**
 *  为每个对象添加一个数组属性
 */
@property (nonatomic,strong) NSArray *books;
@end

实现代码:

// 用一个字节来存储key值,设置为静态私有变量,避免外界修改
static char nameKey;
- (void)setName:(NSString *)name
{
    // 将某个值与某个对象关联起来,将某个值存储到某个对象中
    objc_setAssociatedObject(self, &nameKey, name, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

- (NSString *)name
{
     return objc_getAssociatedObject(self, &nameKey);
}

static char booksKey;
- (void)setBooks:(NSArray *)books
{
    objc_setAssociatedObject(self, &booksKey, books, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSArray *)books
{
    return objc_getAssociatedObject(self, &booksKey);
}

测试:

NSString *str = @"xx";
str.name = @"oo";
str.books = @[@"xxoo",@"ooxx"];
NSLog(@"%@,%@",str.name,str.books);

打印如下

2016-08-23 12:18:37.642 RunTimeTest[1801:95084] oo,(
    xxoo,
    ooxx
)
(lldb) 

这样连字符串页具备了一个数组属性。

三、对象关联的另一种作用:在既有类中使用关联对象存放自定义数据

在ios开发时经常会用到UIAlertView类,该类提供了一种视图向用户展示警告信息。该类通过代理协议来处理用户的点击事件,但由于使用了代理就必须把创建警告的视图和处理按钮动作的代码分开,比如说

- (void)showAlertView
{
    UIAlertView *alert =  [[UIAlertView alloc] initWithTitle:@"UIAlertView" message:@"what do you do" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"sure", nil];
    [alert show];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (0 == buttonIndex) {
        NSLog(@"%@",@"cancel");
    }
    else if (1 == buttonIndex)
    {
        NSLog(@"%@",@"sure");
    }
}

如果想在同一个类里处理多个警告信息视图,我们必须在代理方法中比较点击按钮的索引,并借此编写相应的逻辑,如果能够在创建警告视图的时候直接把处理逻辑的代码写好那将会很便于阅读,这时可以考虑用关联对象,设定一个与alert对象关联的代码块,等到执行代理方法时再将其读取出来

- (void)viewDidLoad {
    [super viewDidLoad];
    [self showAlertView];
}
static char myAlerViewKey;
- (void)showAlertView
{
    UIAlertView *alert =  [[UIAlertView alloc] initWithTitle:@"UIAlertView" message:@"what do you do" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"sure", nil];

    // 将逻辑定义到代码块里面
    void(^block)(NSInteger) = ^(NSInteger buttonIndex) {
        if (buttonIndex == 0)
        {
            NSLog(@"%ld",buttonIndex);
        }
        else
        {
            NSLog(@"%ld",buttonIndex);
        }
    };

    // 对象关联
    objc_setAssociatedObject(alert, &myAlerViewKey, block, OBJC_ASSOCIATION_COPY);

    [alert show];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    void(^block)(NSInteger) = objc_getAssociatedObject(alertView, &myAlerViewKey);
    block(buttonIndex);
}

执行效果如下:

每个对象的属性互不干扰

时间: 2024-10-27 12:08:57

Runtime应用(二)使用对象关联为分类增加属性(每个对象的属性互不干扰)的相关文章

快速上手Runtime(二)之给分类添加属性

我们都知道,分类是不能直接添加属性的,那么我们有时候又需要实现这个功能,那么我们应该怎么办才能为分类添加上属性呢. Runtime给分类添加属性原理 给一个类声明属性,其实本质就是给这个类添加关联,并不是直接把这个值的内存空间添加到类存空间. Runtime给分类添加属性步骤 1.在分类的.h文件中声明想要定义的属性 2.在分类的.m文件中实现getter和setter方法 3.引入runtime头文件,然后在setter方法中用objc_setAssociatedObject关联对象 比如给N

iOS开发——实用技术OC篇&给分类增加属性

给分类增加属性 关于分类的创建这里就不扯了,咱们直接开干 这里以文本看占位文字颜色为例一:简单方式(关键技术:KVC)1.在头文件定义一个属性 1 @property (nonatomic, strong) UIColor *placeholderColor; 2 /** 3 * 分类中只会产生属性对应Setter和Getter方法的声明,不会有实现,需要我们自己实现 4 */ 5 //-(void)setPlaceholderColor:(UIColor *)placeholderColor;

《Objective-C Runtime分析(二)-Class,Method,SEL,IMP》

本系列主要参考资料:Objective-C Runtime ReferenceObjective-C Runtime Programming Guide涉及主要文件:objc/message.h,objc/objc-api.h,objc/objc.h,objc/runtime.h 特酷吧[tekuba.net]采用"署名-非商业用途-保持一致"的创作共用协议,使用本文内容请遵循该协议 Objective-C Runtime是Objective-C的基础内容,理解了Objective-C

iOS runtime实战应用:关联对象

在开始之前建议先阅读iOS runtime的基础理解篇:iOS内功篇:runtime 有筒子在面试的时候,遇到这样一个问题:"如何給NSArray添加一个属性(不能使用继承)",筒子立马蒙逼了,不能用继承,难道用分类?但是分类貌似只能添加方法不能添加属性啊,筒子百思不得其解,直到后来接触到了runtime才恍然大悟. 什么是关联对象 关联对象是指某个OC对象通过一个唯一的key连接到一个类的实例上.举个例子:xiaoming是Person类的一个实例,他的dog(一个OC对象)通过一根

runtime之通过objc_setAssociatedObject关联及传值

关联 关联是指把两个对象相互关联起来,使得其中的一个对象作为另外一个对象的一部分.关联特性只有在Mac OS X V10.6以及以后的版本上才是可用的. 在类的定义之外为类增加额外的存储空间 使用关联,我们可以不用修改类的定义而为其对象增加存储空间.这在我们无法访问到类的源码的时候或者是考虑到二进制兼容性的时候是非常有用.关联是基于关键字的,因此,我们可以为任何对象增加任意多的关联,每个都使用不同的关键字即可.关联是可以保证被关联的对象在关联对象的整个生命周期都是可用的(在垃圾自动回收环境下也不

PGM学习之二 PGM模型的分类与简介

废话:和上一次的文章确实隔了太久,希望趁暑期打酱油的时间,将之前学习的东西深入理解一下,同时尝试用Python写相关的机器学习代码. 一 PGM模型的分类 通过上一篇文章的介绍,相信大家对PGM的定义和大致应用场景有了粗略的了解.那么接下来我们来深入了解下PGM. 首先要介绍的是Probabilistic models(概率模型),常用来描述不同的随机变量之前的关系,主要针对变量或变量间的相互不确定性的概率关系建模.总的来说,概率模型分为两类: 一类是参数模型-可以用有限个参数进行准确定义 参数

(转发)IOS高级开发~Runtime(二)

一些公用类: @interface ClassCustomClass :NSObject{ NSString *varTest1; NSString *varTest2; NSString *varTest3; } @property (nonatomic,assign)NSString *varTest1; @property (nonatomic,assign)NSString *varTest2; @property (nonatomic,assign)NSString *varTest3

iOS runtime探究(二): 从runtime開始深入理解OC消息转发机制

你要知道的runtime都在这里 转载请注明出处 http://blog.csdn.net/u014205968/article/details/67639289 本文主要解说runtime相关知识,从原理到实践.由于包括内容过多分为下面五篇文章详细解说.可自行选择须要了解的方向: 从runtime開始: 理解面向对象的类到面向过程的结构体 从runtime開始: 深入理解OC消息转发机制 从runtime開始: 理解OC的属性property 从runtime開始: 实践Category加入属

属性与内存管理(属性与内存管理都是相互关联的)

<span style="font-size:18px;"> 属性与内存管理(属性与内存管理都是相互关联的)第一部分 一,属性: 属性是OC2.0之后出来的新语法,用来代替setter和getter方法,使用属性可以快速创建setter以及getter方法的声明,setter和getter方法的实现,另外添加了对实例变量操作的安全处理(其安全是通过内存管理实现的) setter 方法作用:为单一的实例变量重新赋值, 规范: (- 号方法)无返回值, 名字以set开头后面加上