1. 说明:随便创建一个页面,里面有一个button,然后点击下,可以看到打印结果(利用runtime实现了拦截效果)
#import "ViewController.h"
#import <objc/runtime.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self sendMethodTest];
}
#pragma mark -- swizMethod test
- (void)sendMethodTest
{
UIButton *_ljBtn = [[UIButton alloc]init];
[_ljBtn setFrame:CGRectMake(100, 150, 150, 100)];
[_ljBtn setBackgroundColor:[UIColor grayColor]];
[_ljBtn setTitle:@"sendMethodTest" forState:UIControlStateNormal];
[_ljBtn addTarget:self action:@selector(clicked:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:_ljBtn];
}
- (void)clicked:(id)sender
{
NSLog(@"%s", __func__);
}
#import "UIControl+LJControl.h"
#import <objc/runtime.h>
@implementation UIControl (LJControl)
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Method origMethod = class_getInstanceMethod([self class], @selector(sendAction:to:forEvent:));
SEL origsel = @selector(sendAction:to:forEvent:);
Method swizMethod = class_getInstanceMethod([self class], @selector(LJControl_sendAction:to:forEvent:));
SEL swizsel = @selector(LJControl_sendAction:to:forEvent:);
BOOL addMehtod = class_addMethod([self class], origsel, method_getImplementation(swizMethod), method_getTypeEncoding(swizMethod));
if (addMehtod)
{
class_replaceMethod([self class], swizsel, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
}
else
{
method_exchangeImplementations(origMethod, swizMethod);
}
});
}
//原方法的指针位置指向交换后的LJControl_sendAction方法。下面的是拦截方法
- (void)LJControl_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event
{
NSLog(@"%s", __func__);
//交换后的方法指针指向的是原方法的指针,就是下面的这个函数。因为上面的方法已经交换过了,所以下面的是点击事件方法
[self LJControl_sendAction:action to:target forEvent:event];
}
@end
3.结果
控制台打印结果:
2017-02-07 16:28:51.419494 ljDemo[1741:679678] -[UIControl(LJControl) LJControl_sendAction:to:forEvent:]
2017-02-07 16:28:51.419778 ljDemo[1741:679678] -[ViewController clicked:]
从打印结果可以看出,点击事件的拦截方法先执行,点击事件方法后执行。通过上面的方法,可以做一些埋点工作或者用户行为数据的获取。