一般我们会利用类别添加一些类方法,然后直接调用。我在做复制粘贴的时候写了UIPasteboard
的类别,但是发现需要添加属性才能完成达到我的需求,但是直接添加属性应用起来会报错。于是查了下文档发现,OC的类别允许添加属性,但不会自动生成getter、setter方法。有没有解决方案呢?通过查阅网上的一些资料,发现还是有的,通过runtime黑魔法可以建立关联引用。接下来以添加一个这样的属性为例。
1.引入运行时头文件
#import <objc/runtime.h>
2、添加属性
@property (nonatomic, strong) ChatMessageDetail * chatMessageDetail;
3、setter方法
- (void)setChatMessageDetail:(ChatMessageDetail *)chatMessageDetail { objc_setAssociatedObject(self, &strKey, chatMessageDetail, OBJC_ASSOCIATION_RETAIN_NONATOMIC); }
set方法使用了OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
这个方法有四个参数,源对象,关联的key,关联对象,关联的策略。我的理解就是通过这个关联key 吧源对象和关联的对象关联起来,所有这个key应该是唯一的。所以代码中用的key 是一个静态变量的地址。static void *strKey = &strKey;
关联策略的话,看文档有几种选择,看名字很直观。但是还是并不很清楚该怎么选择。
enum{ OBJC_ASSOCIATION_ASSIGN = 0, OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, OBJC_ASSOCIATION_COPY_NONATOMIC = 3, OBJC_ASSOCIATION_RETAIN = 01401, OBJC_ASSOCIATION_COPY = 01403 }
4、getter方法,不需多说
- (ChatMessageDetail *)chatMessageDetail { return objc_getAssociatedObject(self, &strKey); }
static void *strKey = &strKey;
5、补充除了setter与getter还有些相关的API。移除所有关联对象
OBJC_EXPORT void objc_removeAssociatedObjects(id object)