Effective Objective-C 2.0 编撰高质量iOS与OS X代码 在既有类中使用关联对象存放自定义数据

Effective Objective-C 2.0 编写高质量iOS与OS X代码 在既有类中使用关联对象存放自定义数据
1. 可以通过“关联对象”机制来把两个对象连起来。

2. 定义关联对象时,可指定内存管理语义,用以模仿定义属性时所采用的“拥有关系”和“非拥有关系”。

3. 只有再其他做法不可行时才应选择关联对象,因为这种做法通常会引入难以查找的bug。


有时候类的实例可能是某种机制所创建,而开发者无法令这种机制创建出自己所写的子类实例。
可以给某对象关联许多其他对象。这些对象会通过“键”来区分。
存储对象值的时候,可以指明“存储策略”,用以维护相应的“内存管理语义”。
存储策略由名为objc_AssociationPolicy 的枚举定义。
如果关联对象成了属性,那么它就会具备对应的语义。
关联类型 等效的@property属性
OBJC_ASSOCIATION_ASSIGN ASSIGN
OBJC_ASSOCIATION_RETAIN_NONATOMIC nonatomic,retain
OBJC_ASSOCIATION_COPY_NONATOMIC nonatomic,copy
OBJC_ASSOCIATION_RETAIN retain
OBJC_ASSOCIATION_COPY copy

以下方法用来管理关联对象:
① void objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy);
此方法以给定的键和策略为某对象设置关联对象值。

② void objc_getAssociatedObject(id object, void *key);
此方法根据给定的键从某对象中获取相应的关联对象值。

③ void objc_removeAssociatedObjects(id object);
此方法移除指定对象的全部关联对象。

4. 设置关联对象用的键是个“不透明的指针”,即所指向的数据结构不局限于某种特定类型的指针。
再设置关联对象值时,若想令两个键匹配到同一个值,则二者必须时完全相同的指针才行。
跟NSDictionary不一样。NSDictionary认为“isEqual:”返回YES,则二者相同。
故设置关联对象值时,通常使用静态全局变量做键。

5.例子:
static void *MyAlertViewKey = “MyAlertViewKey”;
- (void) askUserQuestion
{
     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@“Question” message:@“What?” delegate:self cancelButtonTitle:@“cancel” otherButtonTitles:@“Continue”,nil];

     void (^block)(NSInteger) = ^(NSInteger buttonIndex){
          if(buttonIndex == 0){
               [self doCancel];
          } else {
               [self doContinue];
          }
     };
     
     objc_setAssociatedObject(alert, MyAlertViewKey, block, BJC_ASSOCIATION_COPY);
     [alert show];
}

- (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
     void (^block)(NSInteger) = objc_getAssociatedObject (alertView, MyAlertViewKey);
     block(buttonIndex);
}



摘取自:《Effective Objective-C 2.0 编写高质量iOS与OS X代码的52个有效方法》,详细请购买书籍,支持作者及译者。