小工具      在线工具  汉语词典  css  js  c++  java

ios运行时swizMethod拦截交换方法执行

IOS系统方法&&常用控件&&GitHub资源学习 额外说明

收录于:43天前

1、说明:只要创建一个页面,里面有一个按钮,然后点击就可以看到打印结果(使用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__);
}


2.创建一个 UIControl类,用于实现拦截操作。

#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:]


4.结论

从打印结果可以看出,点击事件的拦截方法先执行,点击事件方法后执行。通过上面的方法,可以做一些埋点工作或者用户行为数据的获取。


. . .

相关推荐

额外说明

字符串变形(字符串大小写切换和变现)

补充基本知识: JAVA中String类提供了转大写的方法toUpperCase()和转小写的方法toLowerCase() String a = "ABC"; system.out.println(a.toLowerCase());//abc Stri

额外说明

TP5+商城小程序——专题、分类、商品详情接口编写-编写Theme详情接口

QQ 1274510382 Wechat JNZ_aming 商业联盟 QQ群538250800 技术搞事 QQ群599020441 解决方案 QQ群152889761 加入我们 QQ群649347320 共享学习 QQ群674240731 纪年科技am

额外说明

Java后台——点餐小程序餐厅人员管理页代码的讲解

QQ 1274510382 Wechat JNZ_aming 商业互捧 QQ群538250800 技术搞事 QQ群599020441 技术合作 QQ群152889761 加入我们 QQ群649347320 纪年科技aming 网络安全 ,深度学习,嵌入式

额外说明

auto.js启动app

CODE: // 启动app的方式 app.launchApp("QQ"); // 获取应用的包名 var name = getPackageName("QQ"); log(name);  

额外说明

Java编程的精髓:深入理解JVM和性能优化

文章目录 Java虚拟机(JVM)的核心概念 1. 类加载器(Class Loader) 2. 内存区域 3. 垃圾回收(Garbage Collection) 4. 类型转换和多态 JVM性能调优 1. JVM参数调整 2. 内存管理 3. 多线程优化

额外说明

【小吉送书—第二期】阿里后端开发:抽象建模经典案例

文章目录 0.引言 1.抽象思维 2.软件世界中的抽象 2.1 命名抽象 2.2 分层抽象 2.3 原则抽象 3. 经典抽象案例 3.1 方案一:战术抽象,多快好省,跑步前进 3.2 方案二:深入分析,透过表象,探寻本质 5. 推荐一本书 -彩蛋 0.引

额外说明

【Python 千题 —— 基础篇】除法计算

题目描述 题目描述 编写一个程序,接受用户输入的两个数字,然后计算这两个数字的除法结果,并输出结果。 输入描述 输入两个数字,用回车隔开两个数字。 输出描述 程序将计算这两个数字的除法结果,并输出结果。 示例 示例 ① 1 2 输出: 0.5 代码讲

额外说明

Spring Boot 跨域访问的实现方式最全汇总

关于跨域访问的介绍, 参考 跨域访问的相关概念及解决方法。 在基于Spring Boot框架的应用中, 需要跨域访问的场景有很多, 比如: 应用内部: 在前后端分离的框架中, Spring Boot 提供后端服务 应用外部: 作为微服务,提供对外的Res

额外说明

Spring学习笔记:配置单数据源

Spring学习笔记:配置单数据源 一、Spring Boot默认数据源类型 Springboot默认支持4种数据源类型,定义在 org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConf

额外说明

【软考 系统架构设计师】计算机网络④ IPv6

>>回到总目录<< 为了不辜负已经订阅了专栏的同学们的信任,所以本专栏不会有任何的优惠活动。 另外,当订阅人数每次达到 2 n ( n > 2 ) 2^n(n>2) 2

ads via 小工具