《Effective Objective-C 2.0》摘抄(3)- 关联对象

       在既有类中使用关联对象存放自定义数据;有时候需要在对象中存放相关信息。这时我们通常会从对象的所属的类中继承一个子类,然后改用这个子类对象。然而并非所有情况下都能这么做,有时候类的实例可能是由某种机制所创建的,而开发者,无法令这种机制创建出自己所写的子类实例。 OC 中有一项强大的特性可以解决此问题,这就是“关联对象”(Associate Object)。

关联对象类型(policy):

《Effective Objective-C 2.0》摘抄(3)- 关联对象_第1张图片
关联类型与属性比较

关联对象方法:

// ⬇️此方法以给定的键 和策略 为某对象设置关联对象值:

void  objc_setAssociateObject(id *object, void *key, id value, objc_AssociationPolicy policy);

// ⬇️根据指定的键从某对象中获取相应的关联对象值:

void objc_getAssociateObject(id object, void *key);

// ⬇️移除指定对象的全部关联值:

void objc_reomoveAssociatedObjects(id object);

⚠️我们可以把某对象想象成 NSDictionary, 把关联对象的值理解为字典中的条目,于是,存取关联对象的值就相当于给字典赋值、取值;然而两者之间有个很重要的差别是:设置关联对象时用的键是个“不透明的指针”(opaque pointer),在设置关联对象时,若想令两个键匹配到同一个值,则二者必须是完全相同的指针才行,鉴于此,在设置关联对象值时,通常使用静态全局变量作为 键。

#import

@interface ViewController ()

@end

static void *EOCAlertViewKey = "AlertViewKey";

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

// Do any additional setup after loading the view, typically from a nib.

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"This is title" message:@"This is message" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", nil];

alert.delegate = self;

void (^alertHandlerBlock)(NSInteger) = ^(NSInteger index) {

NSLog(@"%@", @(index));

};

objc_setAssociatedObject(alert, EOCAlertViewKey, alertHandlerBlock, OBJC_ASSOCIATION_COPY);

[alert show];

}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {

void(^alertHandlerBlock)(NSInteger) = objc_getAssociatedObject(alertView, EOCAlertViewKey);

alertHandlerBlock(buttonIndex);

}

@end

你可能感兴趣的:(《Effective Objective-C 2.0》摘抄(3)- 关联对象)