本质
动态添加属性,就是让某个属性与对象产生关联。runtime一般都是针对系统的类
开发场景
给系统的类添加属性的时候,可以使用runtime动态添加属性方法。
原理
让一个NSObject类保存一个字符串,可以写一个分类,在分类中属性定义某个变量,这样只会该变量生成set,get方法的声明,不会生成实现,需要自己去写实现方法,也不会生成带下划线的成员变量。
实例
为UIView添加一个字符串类型的tag:UIView默认的 tag 实现只能添加int类型的值,按照现有的语法就没办法存储这个 tag 的实例变量。
1.为UIView添加一个Category,并声明stringTag属性
@interface UIView (StringTag)
@property (nonatomic, copy) NSString *stringTag;
@end
2.实现set和get方法
/**
* @param object 将关联值设置到的实例
* @param key 关联值的标识key
* @param 关联值自身
* @param policy 关联属性的处理方式
*/
- (void)setStringTag:(NSString *)stringTag {
objc_setAssociatedObject(self, @selector(stringTag), stringTag, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
/**
* @param object 关联值所在的对象
* @param key 关联值的标识key
*/
- (NSString *)stringTag {
return objc_getAssociatedObject(self, @selector(stringTag));
}
第二个参数,这里用了 @selector(stringTag) 这种形式。 虽然这个参数代表的是一个 key, 但它的类型不是 NSString, 而是一个 void * 的指针,这就意味着可以将任何符合这个类型条件的值设置给它。@selector(stringTag) 就符合这样的类型,所以不必再定义一个变量来表示这个关联值的 key, 只需要将和他属性名对应的 Selector 传递进来即可。
总结
Associated Object 在平时开发中对 Category 属性的这个应用很常见,比如著名的框架 AFNetworking 里面就对很多 Category 中的属性定义使用了 Associated Object。 可以参看它对 UIImage 的 Categoy 定义。