事件传递和监控

news2025/3/12 12:18:24

今天介绍一下UIApplication的函数 - (BOOL)sendAction:to:from:forEvent:

- (BOOL)sendAction:to:from:forEvent:UIApplication 类中的一个方法,主要用于发送事件响应链中的动作(action)。它允许应用程序从一个特定的发送者(sender)向目标(target)发送一个特定的选择器(action),并且将事件(event)与动作一起传递。

- (BOOL)sendAction:(SEL)action
              to:(nullable id)target
            from:(nullable id)sender
        forEvent:(nullable UIEvent *)event;

参数说明:

  • action: 要发送的动作(SEL 类型),即目标对象应该响应的方法。
  • target: 目标对象,接收 action 的对象。通常是响应事件的视图控制器或视图对象。
  • sender: 发送者对象,通常是触发事件的控件或视图。它是事件源,可以为空。
  • event: 事件对象,包含关于事件的详细信息。可以为空,通常用于触摸事件。

返回值:

  • 返回一个 BOOL 类型的值,表示是否成功发送了该动作。YES 表示成功,NO 表示失败。

使用场景:

此方法通常用于应用程序中触发事件传递的过程中,尤其是在触摸事件和界面控件的交互中。例如,当用户点击按钮时,按钮会触发一个事件,而 sendAction:to:from:forEvent: 方法可以帮助把这个事件传递到目标对象(例如视图控制器)上执行相应的操作。

示例:
// 假设有一个 UIButton,点击时触发相应的动作
UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
[button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];

// 手动发送事件
UIEvent *event = nil;  // 事件对象通常由系统管理,手动调用时可以传入nil
[UIApplication.sharedApplication sendAction:@selector(buttonClicked:) to:self from:button forEvent:event];

在这个例子中,sendAction:to:from:forEvent: 方法会将按钮点击的动作传递到目标对象(self,即当前控制器),并调用 buttonClicked: 方法。

注意:

  • 该方法通常不是直接调用的,而是系统或控件内部在处理事件时使用。
  • 如果目标对象没有实现对应的 action 方法,返回值将是 NO
  • sendAction:to:from:forEvent: 可以用于自定义事件传递,但如果目标对象是某些标准 UI 控件(如按钮、滑块等),通常会通过更简单的事件处理方式(例如使用 addTarget:action:forControlEvents:)来处理。

其他更有效的使用

监控 iOS 系统的点击事件

在 iOS 中,监控点击事件(如用户点击按钮或其他 UI 元素)是非常常见的需求。有时,我们可能需要追踪每个点击事件的发生,或是对其进行拦截和分析。例如,我们希望记录用户的点击行为,或者实现一些自定义的点击逻辑。

通常,iOS 提供了多种方式来处理点击事件,如 UIButtonaddTarget:action:forControlEvents:,或者通过重写 touchesBegantouchesMovedtouchesEnded 等方法。但在一些特殊场景下,我们可以通过方法交换(Method Swizzling)来动态替换系统的点击事件处理方法,从而实现对点击事件的监控。

以下介绍如何利用方法交换来监控 iOS 系统的点击事件,具体实现的步骤如下:

1. 理解 iOS 点击事件的流程

在 iOS 中,点击事件通过触摸事件来传递,UI 元素(如按钮、控件等)会接收到触摸事件并触发相应的动作。例如,当用户点击一个按钮时,按钮的 sendAction:to:from:forEvent: 方法会被调用,进而触发目标对象的 action 方法。

我们可以通过方法交换,替换 UIApplicationUIControlsendAction:to:from:forEvent: 方法,从而在不修改现有代码的情况下,监听并拦截所有的点击事件。

2. 方法交换简介

方法交换是 Objective-C 中的一种技术,它允许我们动态地交换两个方法的实现。通过方法交换,我们可以在运行时替换一个方法的实现,从而改变其行为。常见的应用场景包括:日志记录、性能分析、事件拦截等。

3. 具体实现:监控点击事件

在这个例子中,我们将通过方法交换来监控 sendAction:to:from:forEvent: 方法的调用,从而捕捉每次点击事件。我们将监控所有 UI 控件的点击事件,并在点击事件发生时输出日志信息。

3.1. 创建 Method Swizzling 方法

首先,我们创建一个 +swizzleSendAction 方法来实现方法交换。我们要交换的目标方法是 sendAction:to:from:forEvent:,目标类是 UIApplication

#import <UIKit/UIKit.h>
#import <objc/runtime.h>

@implementation UIApplication (ClickMonitor)

// 定义一个新的方法,作为替换方法
- (BOOL)swizzled_sendAction:(SEL)action to:(id)target from:(id)sender forEvent:(UIEvent *)event {
    // 在这里记录点击事件信息
    NSLog(@"Action: %@, Target: %@, Sender: %@, Event: %@", NSStringFromSelector(action), target, sender, event);
    
    // 调用原始方法(返回值需要匹配原方法的返回值类型)
    return [self swizzled_sendAction:action to:target from:sender forEvent:event];
}

// 方法交换
+ (void)load {
    // 获取原始方法和新方法
    Method originalMethod = class_getInstanceMethod(self, @selector(sendAction:to:from:forEvent:));
    Method swizzledMethod = class_getInstanceMethod(self, @selector(swizzled_sendAction:to:from:forEvent:));
    
    // 交换方法
    method_exchangeImplementations(originalMethod, swizzledMethod);
}

@end
3.2. 解释代码
  • 我们创建了一个类别(Category),UIApplication (ClickMonitor),为 UIApplication 类添加了一个新的方法 swizzled_sendAction:to:from:forEvent:
  • 在新方法中,我们打印了点击事件的相关信息(例如,actiontargetsenderevent)。
  • 我们使用 method_exchangeImplementations 来交换原始方法 sendAction:to:from:forEvent: 和我们自定义的 swizzled_sendAction:to:from:forEvent: 方法。
  • 每次调用 sendAction:to:from:forEvent: 方法时,实际上会调用我们的替换方法 swizzled_sendAction:to:from:forEvent:,从而实现监控点击事件。
3.3. load 方法的作用

UIApplication 的类别中实现 +load 方法,这是确保方法交换在应用程序启动时执行的常见方式。+load 方法会在类被加载到内存时自动调用,这样我们就可以在应用启动时就完成方法交换。

3.4. 测试点击事件

我们可以通过简单的 UI 测试,确保方法交换成功工作。假设我们有一个按钮,并希望在按钮点击时触发日志输出:

UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
[button setTitle:@"Click Me" forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];

[self.view addSubview:button];

当用户点击按钮时,swizzled_sendAction:to:from:forEvent: 方法将会被调用,并在控制台输出相关的点击事件信息。

4. 注意事项

  • 性能影响:虽然方法交换是强大且灵活的,但它会增加一定的性能开销,因为每次事件都会调用我们自定义的方法。如果有大量的事件需要监控,可能会影响应用的响应速度。
  • 调用链:通过方法交换,我们改变了系统方法的行为,因此需要确保原始方法的调用仍然能够顺利执行。在本例中,我们通过在 swizzled_sendAction 方法的末尾调用原始方法来保持事件传递链的完整。
  • 调试和测试:由于方法交换直接修改了系统行为,可能会影响调试和测试过程。需要在使用方法交换时保持谨慎,确保没有引入难以发现的 bug。

5. 总结

通过方法交换(Method Swizzling),我们能够在运行时修改系统类的方法实现,实现监控 iOS 系统的点击事件。通过替换 sendAction:to:from:forEvent: 方法,我们可以捕捉到所有控件的点击事件,并在其中加入自定义的处理逻辑。虽然方法交换非常强大,但在实际应用中需要小心使用,以避免对性能和系统行为产生不必要的影响。

这种方法为我们提供了在不改变现有代码的情况下,灵活地添加自定义行为的方式,是调试和事件监控中的一种常用技巧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2299832.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CentOS 7 企业级Redis 7部署指南

CentOS 7 企业级Redis 7部署指南 目录导航 一、环境准备 1.1 依赖管理 二、离线安装 2.1 源码编译安装2.2 目录结构规范 三、生产配置 3.1 主配置文件3.2 配置生成脚本 四、系统集成 4.1 Systemd服务文件4.2 服务管理命令 五、安全加固 5.1 网络安全配置5.2 审计配置 六、性能…

消息中间件深度剖析:以 RabbitMQ 和 Kafka 为核心

在现代分布式系统和微服务架构的构建中&#xff0c;消息中间件作为一个不可或缺的组件&#xff0c;承担着系统间解耦、异步处理、流量削峰、数据传输等重要职能。尤其是在面临大规模并发、高可用性和可扩展性需求时&#xff0c;如何选择合适的消息中间件成为了开发者和架构师们…

大语言模型简史:从Transformer(2017)到DeepSeek-R1(2025)的进化之路

2025年初&#xff0c;中国推出了具有开创性且高性价比的「大型语言模型」&#xff08;Large Language Model — LLM&#xff09;DeepSeek-R1&#xff0c;引发了AI的巨大变革。本文回顾了LLM的发展历程&#xff0c;起点是2017年革命性的Transformer架构&#xff0c;该架构通过「…

java八股文-spring

目录 1. spring基础 1.1 什么是Spring&#xff1f; 1.2 Spring有哪些优点&#xff1f; 1.3 Spring主要模块 1.4 Spring常用注解 1.5 Spring中Bean的作用域 1.6 Spring自动装配的方式 1.7 SpringBean的生命周期 1.8 多级缓存 1.9 循环依赖&#xff1f; 1 .8.1 原因 1.8…

NLP 八股 DAY1:BERT

BERT全称&#xff1a;Pre-training of deep bidirectional transformers for language understanding&#xff0c;即深度双向Transformer。 模型训练时的两个任务是预测句⼦中被掩盖的词以及判断输⼊的两个句⼦是不是上下句。在预训练 好的BERT模型后⾯根据特定任务加上相应的⽹…

蓝桥与力扣刷题(230 二叉搜索树中第k小的元素)

题目&#xff1a;给定一个二叉搜索树的根节点 root &#xff0c;和一个整数 k &#xff0c;请你设计一个算法查找其中第 k 小的元素&#xff08;从 1 开始计数&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,1,4,null,2], k 1 输出&#xff1a;1示例 2&#xff…

半遮挡检测算法 Detecting Binocular Half-Occlusions

【1. 背景】&#xff1a; 本文分析【Detecting Binocular Half-Occlusions&#xff1a;Empirical Comparisons of Five Approaches】Geoffrey Egnal和Richard P. Wildes于2002年发表在IEEE Transactions on Pattern Analysis and Machine Intelligence上&#xff0c;这是1篇中…

PHP培训机构教务管理系统小程序

&#x1f511; 培训机构教务管理系统——智慧教育&#xff0c;高效管理新典范 &#x1f680; 这款教务管理系统&#xff0c;是基于前沿的ThinkPHP框架与Uniapp技术深度融合&#xff0c;匠心打造的培训机构管理神器。它犹如一把开启高效运营与精细管理的金钥匙&#xff0c;专为…

无人机不等同轴旋翼架构设计应用探究

“结果显示&#xff0c;对于不等组合&#xff0c;用户应将较小的螺旋桨置于上游以提高能效&#xff0c;但若追求最大推力&#xff0c;则两个相等的螺旋桨更为理想。” 在近期的研究《不等同轴旋翼性能特性探究》中&#xff0c;Max Miles和Stephen D. Prior博士深入探讨了不同螺…

CTFHub技能树-密码口令wp

目录 引言弱口令默认口令 引言 仅开放如下关卡 弱口令 通常认为容易被别人&#xff08;他们有可能对你很了解&#xff09;猜测到或被破解工具破解的口令均为弱口令。 打开环境&#xff0c;是如下界面&#xff0c;尝试一些弱口令密码无果 利用burpsuite抓包&#xff0c;然后爆…

【NLP251】BertTokenizer 的全部 API 及 使用案例

BertTokenizer 是 Hugging Face 的 transformers 库中用于处理 BERT 模型输入的分词器类。它基于 WordPiece 分词算法&#xff0c;能够将文本分割成词汇单元&#xff08;tokens&#xff09;&#xff0c;并将其转换为 BERT 模型可以理解的格式。BertTokenizer 是 BERT 模型的核心…

【MySQL常见疑难杂症】常见文件及其所存储的信息

1、MySQL配置文件的读取顺序 &#xff08;非Win&#xff09;/etc/my.cnf、/etc/mysql/my.cnf、/usr/local/mysql/etc/my.cnf、&#xff5e;/.my.cnf 可以通过命令查看MySQL读取配置文件的顺序 [roothadoop01 ~]# mysql --help |grep /etc/my.cnf /etc/my.cnf /etc/mysql/my.c…

IDEA集成DeepSeek

引言 随着数据量的爆炸式增长&#xff0c;传统搜索技术已无法满足用户对精准、高效搜索的需求。 DeepSeek作为新一代智能搜索技术&#xff0c;凭借其强大的语义理解与深度学习能力&#xff0c;正在改变搜索领域的游戏规则。 对于 Java 开发者而言&#xff0c;将 DeepSeek 集成…

leetcode:627. 变更性别(SQL解法)

难度&#xff1a;简单 SQL Schema > Pandas Schema > Salary 表&#xff1a; ----------------------- | Column Name | Type | ----------------------- | id | int | | name | varchar | | sex | ENUM | | salary | int …

SQLMesh系列教程-3:SQLMesh模型属性详解

SQLMesh 的 MODEL 提供了丰富的属性&#xff0c;用于定义模型的行为、存储、调度、依赖关系等。通过合理配置这些属性&#xff0c;可以构建高效、可维护的数据管道。在 SQLMesh 中&#xff0c;MODEL 是定义数据模型的核心结构&#xff0c;初学SQLMesh&#xff0c;定义模型看到属…

【Leetcode 952】按公因数计算最大组件大小

题干 给定一个由不同正整数的组成的非空数组 nums &#xff0c;考虑下面的图&#xff1a; 有 nums.length 个节点&#xff0c;按从 nums[0] 到 nums[nums.length - 1] 标记&#xff1b;只有当 nums[i] 和 nums[j] 共用一个大于 1 的公因数时&#xff0c;nums[i] 和 nums[j]之…

【第4章:循环神经网络(RNN)与长短时记忆网络(LSTM)— 4.6 RNN与LSTM的变体与发展趋势】

引言:时间序列的魔法钥匙 在时间的长河中,信息如同涓涓细流,绵延不绝。而如何在这无尽的数据流中捕捉、理解和预测,正是循环神经网络(RNN)及其变体长短时记忆网络(LSTM)所擅长的。今天,我们就来一场深度探索,揭开RNN与LSTM的神秘面纱,看看它们如何在时间序列的海洋…

简单几个步骤完成 Oracle 到金仓数据库(KingbaseES)的迁移目标

作为国产数据库的领军选手&#xff0c;金仓数据库&#xff08;KingbaseES&#xff09;凭借其成熟的技术架构和广泛的市场覆盖&#xff0c;在国内众多领域中扮演着至关重要的角色。无论是国家电网、金融行业&#xff0c;还是铁路、医疗等关键领域&#xff0c;金仓数据库都以其卓…

八、SPI读写XT25数据

8.1 SPI 简介 SPI&#xff08;Serial Peripheral Interface&#xff0c;串行外设接口&#xff09;是一种同步串行通信协议&#xff0c;广泛用于嵌入式系统中连接微控制器与外围设备&#xff0c;如传感器、存储器、显示屏等。 主要特点 1. 全双工通信&#xff1a;支持同时发送…

Visionpro 齿轮测量

效果展示 一、题目要求 求出最大值&#xff0c;最小值&#xff0c;平均值 二、分析 1.首先要进行模板匹配 2.划清匹配范围 3.匹配小三角的模板匹配 4.卡尺 5.用找圆工具 工具 1.CogPMAlignTool 2.CogCaliperTool 3.CogFindCircleTool 4.CogFixtureTool 三、模板匹…