一、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...");
}];
控制台输出: