本质

动态添加属性,就是让某个属性与对象产生关联。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 定义。

posted on 2018-10-08 16:34  广坤山货  阅读(186)  评论(0编辑  收藏  举报