如何给一个NSArray添加一个属性,不能使用继承。 分类不能添加属性,只能添加方法。
这时就可以使用关联对象。
关联对象
就是给某个对象关联多个对象,这些对象用一个唯一的key区分。
关联对象一般用于动态的扩展一个对象,但是这一般都是在其他方法不行的事后才会使用,因为关联对象很可能会出现难以查找的bug。
存储关联对象的时候一样有内存管理策略。
OBJC_ASSOCIATION_ASSIGN = 0, assign
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, nonatomic,retain
OBJC_ASSOCIATION_COPY_NONATOMIC = 3, nonatomic,copy
OBJC_ASSOCIATION_RETAIN = 01401, retain
OBJC_ASSOCIATION_COPY = 01403, copy
他们每个都对应OC上的内存管理策略。
具体的方法有三个:
//关联对象
void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)
//获取关联的对象
id objc_getAssociatedObject(id object, const void *key)
//移除关联的对象
void objc_removeAssociatedObjects(id object)
具体的参数:
id object:被关联的对象
const void *key:关联的key,要求唯一
id value:关联的对象
objc_AssociationPolicy policy:内存管理的策略
具体用法:
在一个button的分类里面添加一个timeInterval属性。如果不使用关联对象,这个属性没有作用,也不具有set和get方法。
使用关联对象:
重写get和set方法实现关联。
- (NSTimeInterval)timeInterval
{
return [objc_getAssociatedObject(self, _cmd) doubleValue];
}
- (void)setTimeInterval:(NSTimeInterval)timeInterval
{
objc_setAssociatedObject(self, @selector(timeInterval), @(timeInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
这样就可以在button的分类里面添加一个属性了。
还有一种用法,使用UIAlertview的时候,创建了一个alert对象,还要实现它的代理去处理按钮点击方法。但是当有好多个alert对象创建了之后,他们都要通过同一个代理方法去处理点击事件。
为了区分不同的alert,一般的做法是给每个alert对象加上tag值,在代理方法去获取当前的alert对象。
使用关联对象具体代码:
static char *AlertKey = "alertKey";
- (void)viewDidLoad {
[super viewDidLoad];
alert = [[UIAlertView alloc] initWithTitle:@"alert" message:@"message" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"other", nil];
}
- (IBAction)click:(id)sender {
void (^block) (NSInteger) = ^(NSInteger buttonIndex){
if (buttonIndex == 0){
NSLog(@"click cancel");
}
else{
NSLog(@"click other");
}
};
objc_setAssociatedObject(alert, AlertKey, block, OBJC_ASSOCIATION_COPY);
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex: (NSInteger)buttonIndex
{
void (^block)(NSInteger) = objc_getAssociatedObject(alertView, AlertKey);
block(buttonIndex);
}
如果是用关联对象,就会更方便。在alert创建的时候设置一个关联对象block,并给他一个唯一的key值。创建一个关联对象block,关联当前对象和代理方法,把代理里面需要执行的方法通过block和alert的创建方法绑定。
最后不要忘了import
网友评论