标签:
Associated Objects(关联对象)或者叫作关联引用(Associative References),是作为Objective-C 2.0 运行时功能被引入到 Mac OS X 10.6 Snow Leopard(及iOS4)系统。与它相关在<objc/runtime.h>
中有3个C函数,它们可以让对象在运行时关联任何值:
OBJC_EXPORT void objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy) OBJC_EXPORT id objc_getAssociatedObject(id object, const void *key) OBJC_EXPORT void objc_removeAssociatedObjects(id object)
为什么这几个方法很有用呢?因为开发者可以通过它们在分类中给已存在的类中添加自定义属性。
关于前两个函数中的 key
值是我们需要重点关注的一个点,这个 key
值必须保证是一个对象级别(为什么是对象级别?看完下面的章节你就会明白了)的唯一常量。一般来说,有以下三种推荐的 key
值:
static char kAssociatedObjectKey;
,使用 &kAssociatedObjectKey
作为 key
值;static void *kAssociatedObjectKey = &kAssociatedObjectKey;
,使用 kAssociatedObjectKey
作为 key
值;selector
,使用 getter
方法的名称作为 key
值。
我个人最喜欢的(没有之一)是第 3
种方式,因为它省掉了一个变量名,非常优雅地解决了计算科学中的两大世界难题之一(命名)。
在给一个对象添加关联对象时有五种关联策略可供选择:
/** * OBJC_ASSOCIATION_ASSIGN 等价于@property (assign) , @property (unsafe_unretained) 弱引用关联对象 * OBJC_ASSOCIATION_RETAIN_NONATOMIC 等价于@property (strong, nonatomic) 强引用关联对象,且为非原子操作 * OBJC_ASSOCIATION_COPY_NONATOMIC 等价于@property (copy, nonatomic) 复制关联对象,且为非原子操作 * OBJC_ASSOCIATION_RETAIN 等价于@property (strong, atomic) 强引用关联对象,且为原子操作 * OBJC_ASSOCIATION_COPY 等价于@property (copy, atomic) 复制关联对象,且为原子操作 其中,第 2 种与第 4 种、第 3 种与第 5 种关联策略的唯一差别就在于操作是否具有原子性。 */ objc_setAssociatedObject(button, buttonKey, _imgView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
例子:
1、倒入头文件,声明key:
#import <objc/runtime.h> char* const buttonKey = "buttonKey";
2、设置关联:
if (groupModel.isOpened) { UIImageView * _imgView = [[UIImageView alloc]initWithFrame:CGRectMake(10, (44-16)/2, 14, 16)]; [_imgView setImage:[UIImage imageNamed:@"ico_list"]]; [sectionView addSubview:_imgView]; CGAffineTransform currentTransform = _imgView.transform; CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform, M_PI/2); // 在现在的基础上旋转指定角度 _imgView.transform = newTransform; objc_setAssociatedObject(button, buttonKey, _imgView, OBJC_ASSOCIATION_RETAIN_NONATOMIC); }else{ UIImageView * _imgView = [[UIImageView alloc]initWithFrame:CGRectMake(10, (44-16)/2, 14, 16)]; [_imgView setImage:[UIImage imageNamed:@"ico_list"]]; [sectionView addSubview:_imgView]; objc_setAssociatedObject(button, buttonKey, _imgView, OBJC_ASSOCIATION_RETAIN_NONATOMIC); }
3、获取关联:
- (void)buttonPress:(UIButton *)sender//headButton点击 { GroupModel *groupModel = dataSource[sender.tag]; UIImageView *imageView = objc_getAssociatedObject(sender,buttonKey); if (groupModel.isOpened) { [UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionTransitionNone animations:^{ CGAffineTransform currentTransform = imageView.transform; CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform, -M_PI/2); // 在现在的基础上旋转指定角度 imageView.transform = newTransform; } completion:^(BOOL finished) { }]; }else{ [UIView animateWithDuration:0.3 delay:0.0 options: UIViewAnimationOptionAllowUserInteraction |UIViewAnimationOptionCurveLinear animations:^{ CGAffineTransform currentTransform = imageView.transform; CGAffineTransform newTransform = CGAffineTransformRotate(currentTransform, M_PI/2); // 在现在的基础上旋转指定角度 imageView.transform = newTransform; } completion:^(BOOL finished) { }]; } groupModel.isOpened = !groupModel.isOpened; [expandTable reloadSections:[NSIndexSet indexSetWithIndex:sender.tag] withRowAnimation:UITableViewRowAnimationAutomatic]; }
标签:
原文地址:http://www.cnblogs.com/HOYF/p/5658627.html