一、Runtime关联对象的方法简介:

在<objc/runtime.h>中,有三个关联的方法,分别是:

objc_setAssociatedObject

objc_getAssociatedObject

objc_removeAssociatedObjects

1.1、设置关联

void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)

第一个参数:id object : 表示关联的源对象
第二个参数:const void *key : 获取被关联者的索引key
第三个参数:id value : 被关联者
第四个参数:objc_AssociationPolicy policy : 关联策略,一般使用OBJC_ASSOCIATION_RETAIN_NONATOMIC

objc_AssociationPolicy是一个枚举类型,一共为5种:

typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
    OBJC_ASSOCIATION_ASSIGN = ,           /**< Specifies a weak reference to the associated object. */
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = , /**< Specifies a strong reference to the associated object.
                                            *   The association is not made atomically. */
    OBJC_ASSOCIATION_COPY_NONATOMIC = ,   /**< Specifies that the associated object is copied.
                                            *   The association is not made atomically. */
    OBJC_ASSOCIATION_RETAIN = ,       /**< Specifies a strong reference to the associated object.
                                            *   The association is made atomically. */
    OBJC_ASSOCIATION_COPY =           /**< Specifies that the associated object is copied.
                                            *   The association is made atomically. */
};

1.2、获取关联

id objc_getAssociatedObject(id object, const void *key)

同上:

第一个参数:id object : 表示关联的源对象
第二个参数:const void *key : 获取被关联者的索引key

1.3、移除关联

void objc_removeAssociatedObjects(id object)

只有一个参数id object,是关联的源对象。作用就是移除object的所有关联。

二、Runtime关联对象的简单应用:

下面以UIButton为例,使用关联对象完成一个功能函数:为UIButton增加一个Category,定义一个方法,使用block去实现button的点击回调。

UIButton+Addition.h

#import <UIKit/UIKit.h>
#import <objc/runtime.h>    // 导入头文件

// 声明一个button点击事件的回调block
typedef void(^ButtonClickCallBack)(UIButton *button);
@interface UIButton (Addition)

// 为UIButton增加的回调方法
- (void)handleClickCallBack:(ButtonClickCallBack)callBack;

@end

UIButton+Addition.m

#import "UIButton+Addition.h"

// 声明一个静态的索引key,用于获取被关联对象的值
static char *buttonClickKey;
@implementation UIButton (Addition)

- (void)handleClickCallBack:(ButtonClickCallBack)callBack {
    // 将button的实例与回调的block通过索引key进行关联:
    objc_setAssociatedObject(self, &buttonClickKey, callBack, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    // 设置button执行的方法
    [self addTarget:self action:@selector(buttonClicked) forControlEvents:UIControlEventTouchUpInside];
}

- (void)buttonClicked {
    // 通过静态的索引key,获取被关联对象(这里就是回调的block)
    ButtonClickCallBack callBack = objc_getAssociatedObject(self, &buttonClickKey);

    if (callBack) {
        callBack(self);
    }
}

@end

在ViewController中,导入我们写好的分类头文件,定义一个button对象,调用方法分类中的这个方法:

[self.testButton handleClickCallBack:^(UIButton *button) {
        NSLog(@"click...");
}];

控制台输出:

iOS开发--Runtime的简单使用之关联对象的更多相关文章

  1. iOS开发-Runtime详解

    iOS开发-Runtime详解 简介 Runtime 又叫运行时,是一套底层的 C 语言 API,其为 iOS 内部的核心之一,我们平时编写的 OC 代码,底层都是基于它来实现的.比如: [recei ...

  2. iOS开发UI篇—简单介绍静态单元格的使用

    iOS开发UI篇—简单介绍静态单元格的使用 一.实现效果与说明 说明:观察上面的展示效果,可以发现整个界面是由一个tableview来展示的,上面的数据都是固定的,且几乎不会改变. 要完成上面的效果, ...

  3. iOS开发网络篇—简单介绍ASI框架的使用

    iOS开发网络篇—简单介绍ASI框架的使用 说明:本文主要介绍网络编程中常用框架ASI的简单使用. 一.ASI简单介绍 ASI:全称是ASIHTTPRequest,外号“HTTP终结者”,功能十分强大 ...

  4. iOS开发UI篇—简单的浏览器查看程序

    iOS开发UI篇—简单的浏览器查看程序 一.程序实现要求 1.要求 2. 界面分析 (1) 需要读取或修改属性的控件需要设置属性 序号标签 图片 图片描述 左边按钮 右边按钮 (2) 需要监听响应事件 ...

  5. iOS开发Swift篇—简单介绍

    iOS开发Swift篇—简单介绍 一.简介 Swift是苹果于2014年WWDC(苹果开发者大会)发布的全新编程语言 Swift在天朝译为“雨燕”,是它的LOGO 是一只燕子,跟Objective-C ...

  6. 李洪强iOS开发之- 实现简单的弹窗

     李洪强iOS开发之- 实现简单的弹窗 实现的效果:  112222222222223333333333333333

  7. iOS 开发-- Runtime 1小时入门教程

    1小时让你知道什么是Objective-C Runtime,并对它有一定的基本了解,可以在开发过程中运用自如. 三.Objective-C Runtime到底是什么东西? 简而言之,Objective ...

  8. iOS开发基础-KVC简单介绍

    一.KVC介绍 键值编码(Key Value Coding,KVC):使开发者不必进行任何操作就可以进行属性的动态读写. KVC操作方法由 NSKeyValueCoding 协议提供,而 NSObje ...

  9. 【iOS开发】NSOperation简单介绍

    iOS开发多线程篇—NSOperation简单介绍 一.NSOperation简介 1.简单说明 NSOperation的作⽤:配合使用NSOperation和NSOperationQueue也能实现 ...

随机推荐

  1. JDBC连接数据库(二)——连接池

    参考博客:http://www.cnblogs.com/xdp-gacl/p/4002804.html 一. 应用程序直接建立数据库连接模型 应用程序直接每次访问数据库时,都建立创建一个数据库的链接, ...

  2. SpringMVC总结的部分教程及使用方法

    注:本文只用注解来实现 SpringMVC各种流程图流程图(其他的各种流程图)jsp.xml.action彼此之间的关系,都如何使用spring-mvc.xml如何配置,放在哪里?action中如何转 ...

  3. IOS缓存管理之PINCache使用

    前言: 今年重点在于公司iOS架构的梳理工作,上周整理了http请求接口管理与解耦,接下来准备整理一下项目中的缓存处理,目前项目中使用的是PINCache,去年加入这个开源框架时并没有对这个框架进行了 ...

  4. 关于c语言中栈和堆释放的问题

    #include<iostream> #include<string> using namespace std; int main() { string st; cin> ...

  5. BZOJ 3653: 谈笑风生(DFS序+可持久化线段树)

    首先嘛,还是太弱了,想了好久QAQ 然后,这道题么,明显就是求sigma(size[x]) (x是y的儿子且层树小于k) 然后就可以发现:把前n个节点按深度建可持久化线段树,就能用前缀和维护了 其实不 ...

  6. 存储过程与SQL语句如何选择

    58到家数据库30条军规,有一条是“禁止使用存储过程.视图.触发器.Event”, 高并发大数据的互联网业务,架构设计思路是“解放数据库CPU,将计算转移到服务层”, 并发量大的情况下,这些功能很可能 ...

  7. Ant 警告:sun.misc.BASE64Decoder 是 Sun 的专用 API,可能会在未来版本中删除

    如果你用Ant编译项目,而且在项目中用了SUN的专用API,你会得到警告信息,然后Ant会报告编译失败: 这当然是不合理的,javac只是警告而已,ant凭什么就直接报失败呢? 其实最好的解决办法是避 ...

  8. 在Eclipse上通过插件获取github上的spring源码

    spring源码开始的时候是通过SVN来管理代码的,后来是转移到github上管理源码的,可以通过在github上直接下载spring的源码. 下面讲解如何通过在eclipse上的插件git来获取sp ...

  9. 第二章 mac上运行第一个appium实例

    一.打开appium客户端工具 1      检查环境是否正常运行: 点击左边第三个图标 这是测试你环境是否都配置成功了 2      执行的过程中,遇到Could not detect Mac OS ...

  10. Single Number leetcode

    Given an array of integers, every element appears twice except for one. Find that single one. Note:Y ...