runtime结合category和block动态增加方法以及属性

objective-c中,可以在不修改源码的基础上增加方法,或者动态增加属性:
用到的是runtime中的东西:

// 设置
// id object 源对象 -指定我们需要绑定的对象,e.g ,给UIButton添加事件,给Class加属性
// const void *key 设置一个静态常亮,也就是Key 值,通过这个我们可以找到我们关联对象的那个数据值
// id value 关联的对象,e.g 添加的事件或者属性
// objc_AssociationPolicy policy 关联的策略
objc_setAssociatedObject(<#id object#>, <#const void *key#>, id value, <#objc_AssociationPolicy policy#>);
// 获取
// 得到的是关联的对象
objc_getAssociatedObject(<#id object#>, <#const void *key#>)

示例:

static char overviewKey;  
NSArray * array =[[NSArray alloc] initWidthObjects:@"One", @"Two", @"Three", nil];  
//为了演示的目的,这里使用initWithFormat:来确保字符串可以被销毁  
NSString * overview = [[NSString alloc] initWithFormat:@"@",@"First three numbers"];  
objc_setAssociatedObject(array, &overviewKey, overview, OBJC_ASSOCIATION_RETAIN);  

[overview release];  
//(1) overview仍然是可用的  

[array release];  
//(2)overview 不可用 
// 想获取overview
NSString * overview = objc_getAssociatedObject(self, &overviewKey);

下面先code一个动态为vc的button添加事件的例子:

扩展UIButton
UIButton+block.h文件

#import <UIKit/UIKit.h>
#import <objc/runtime.h>
// 用block传递事件
typedef void(^ButtonBlock)(NSInteger index);

@interface UIButton (Block)
// 传递block
- (void)ActionWithBlock:(ButtonBlock) block;

@end

UIButton+block.m文件

#import "UIButton+Block.h"
static const char btnKey;

@implementation UIButton (Block)

- (void)ActionWithBlock:(ButtonBlock) block {
  if (block) {
  // 动态为UIButton关联block
    objc_setAssociatedObject(self, &btnKey, block, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
  }
  [self addTarget:self action:@selector(action:) forControlEvents:UIControlEventTouchUpInside];
}
// 点击事件中执行动态关联的block,实现 动态增加方法
- (void)action:(UIButton *)sender {
  ButtonBlock block = objc_getAssociatedObject(self, &btnKey);
  block(sender.tag);
}

@end

VC中使用:

// 添加正常button点击事件
[_btn addTarget:self action:@selector(action) forControlEvents:UIControlEventTouchUpInside];

// 动态增加的button点击事件
[_btn ActionWithBlock:^(NSInteger index) {
    NSLog(@"点击了第%ld个按钮", index);
}];

- (void)action {
  NSLog(@"正常的点击事件");
}

接下来,动态为UIButton增加属性:
扩展UIButton
UIButton+block.h文件

#import <UIKit/UIKit.h>
#import <objc/runtime.h>
@interface UIButton (Block)
// 动态增加属性
@property (strong, nonatomic) UIImage *drImg;

@end

UIButton+block.m文件

#import "UIButton+Block.h"
static const char propertyKey;

@implementation UIButton (Block)
#pragma mark -
#pragma mark 动态增加属性
- (void)setDrImg:(UIImage *)drImg {
  objc_setAssociatedObject(self, &propertyKey, drImg, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

- (UIImage *)drImg {
  return objc_getAssociatedObject(self, &propertyKey);
}
@end

然后可以像UIButton的其他属性一样使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值