iOS 运行时 ---- 关联对象 block 属性应用

1、项目需求

同一个类有多个alertView, 不同的alertView 点击确定按钮 执行的方法不同

alertOne 点击 确定按钮 执行 methodOne, alertTwo 点击确定按钮 执行 methodTwo

目标:使用关联属性,简化代理方法的使用。
方案:利用关联属性的属性添加方法+自定义block的特性(可以传参数,可以传递函数)。

2、常规方法

初始化并显示 alertOne

  • (IBAction)showAlertOne:(id)sender {
    UIAlertView *alertOne = [[UIAlertView alloc]initWithTitle:@"AlertOne" message:@"" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
    [alertOne setTag:1];
    [alertOne show];
    }
    初始化并显示alertTwo

  • (IBAction)showAlertTwo:(id)sender {
    UIAlertView *alertTwo = [[UIAlertView alloc]initWithTitle:@"AlertTwo" message:@"" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
    [alertTwo setTag:2];
    [alertTwo show];
    }

实现代理

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0) {
return;
}
if (alertView.tag == 1) {
if (buttonIndex == 1) {
[self methodOne];
}
}
else if (alertView.tag == 2) {
if (buttonIndex == 1) {
[self methodTwo];
}
}
}

3、关联属性做法

import runtime.h,定义属性关联key

#import "ViewController.h"
#import 
static void *alertViewKey = "alertViewKey";

初始化并显示 alertOne,同时定义block,将block 与 alertOne 关联

- (IBAction)showAlertOne:(id)sender {
UIAlertView *alertOne = [[UIAlertView alloc]initWithTitle:@"AlertOne" message:@"" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];

void (^block)(NSInteger) = ^(NSInteger buttonIndex) {
    if (buttonIndex == 1) {
        [self methodOne];
    }
};

objc_setAssociatedObject(alertOne, alertViewKey, block, OBJC_ASSOCIATION_COPY);//将block 与 alertOne 关联
[alertOne show];

初始化并显示 alertTwo,同时定义block,将block 与 alertTwo 关联

- (IBAction)showAlertTwo:(id)sender {
UIAlertView *alertTwo = [[UIAlertView alloc]initWithTitle:@"AlertTwo" message:@"" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];

void (^block)(NSInteger) = ^(NSInteger buttonIndex) {
    if (buttonIndex == 1) {
        [self methodTwo];
    }
};

objc_setAssociatedObject(alertTwo, alertViewKey, block, OBJC_ASSOCIATION_COPY);
[alertTwo show];

}

实现代理,在代理方法中,直接取出当前alert 所关联上的 block,再将buttonIndex 传入,让block 自己调用对应方法

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 0) {
        return;
    }
    void(^block)(NSInteger) = objc_getAssociatedObject(alertView, alertViewKey);
    block(buttonIndex);
}

4、比较

使用Assiociated object 方法好处:

1、简化代码
2、代码层次清晰
3、block灵活应用。

参考链接:

runtime关联对象

关联对象常规属性应用

你可能感兴趣的:(iOS 运行时 ---- 关联对象 block 属性应用)