什么叫关联对象技术?说通俗一点,我们都知道用Category类别可以给一些类添加方法,但是不能添加新属性,那怎么添加属性呢?一种直接的方法是继承,但如果只是为了添加一个属性就去做一次继承,还是有点重,这时候,就可以用关联对象的方法。
注意事项:
- 在分类中可以添加方法;
- 在分类中不能增加成员变量;
- 在分类中理论上不可以添加属性,但是利用runtime可以,这里属性不可以保留值,因为分类中没有成员变量,不会生成 _变量,不会自动实现
setter
和getter
方法,需要手动的实现setter
和getter
方法; - 在分类中可以重写原有类的方法,但是会覆盖掉原来的方法;
- 方法调用的优先级:分类-->原来的类-->父类;
- Category理论上不能添加变量,但是可以使用@dynamic 来弥补这种不足。
@dynamic variable;
- (id) variable
{
return objc_getAssociatedObject(self, externVariableKey);
}
- (void)setVariable:(id) variable
{
objc_setAssociatedObject(self, externVariableKey, variable, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
所以我们可以利用 runtime
来实现:
- 在程序运行时,动态的给对象添加属性:
- objc_setAssociatedObject(<#id object#>, <#const void *key#>, <#id value#>, <#objc_AssociationPolicy policy#>)
// setter
-(void)setUrl1:(NSString *)url1
{
/*参数:
* id object 给哪个对象的属性赋值
const void *key 属性对应的key
id value 设置属性值为value
objc_AssociationPolicy policy 使用的策略,是一个枚举值,和copy,retain,assign是一样的,手机开发一般都选择NONATOMIC
*/
objc_setAssociatedObject(self, urlKey, url1, OBJC_ASSOCIATION_COPY_NONATOMIC);
}
- 在程序运行时,动态的获取对象的属性:
- objc_getAssociatedObject(<#id object#>, <#const void *key#>)
// getter
-(NSString *)url1
{
return objc_getAssociatedObject(self, urlKey);
}
- 移除关联对象:
- objc_removeAssociatedObjects(<#id object#>)
// 移除关联对象
-(void)dealloc
{
objc_removeAssociatedObjects(self);
}
详情请戳:
Demo地址:https://github.com/Reminiscencexing/-Category-