iOS中AOP与Method Swizzling 项目中的应用

引子:项目中需要对按钮点击事件进行统计分析,现在项目中就是在按钮的响应代码中添加点击事件,非常繁琐。所以使用了AOP(面向切面编程),将统计的业务逻辑统一抽离出来。

项目中添加的开源库:https://github.com/steipete/Aspects

Method Swizzling 利用runtime交换了函数 SEL A,IMP A 与 SEL  B,IMP B,这一黑魔法使得抽离业务逻辑变的可能。

更多资料可以参考:http://www.cocoachina.com/ios/20150120/10959.html

我处理的过程是新建了一个类用于处理AOP,暂且叫Aspect类

+ (void)load {

[super load];

[Aspect sharedInstance];

}

+ (instancetype)sharedInstance {

static CGAspect *_shared = nil;

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

_shared = [[CGAspect alloc] init];

});

return _shared;

}

- (instancetype)init

{

self = [super init];

if (self) {

[self CG_hook_UIButton];

}

return self;

}

-(void)CG_hook_UIButton {

[UIButton aspect_hookSelector:@selector(sendAction:to:forEvent:) withOptions:0 usingBlock:^(id<AspectInfo> info) {

UIButton *btn = [info instance];

NSString *str = btn.buriedPointTag;

if (str.length > 0) {

    //在这里处理统计的模块

}

} error:NULL];

}

主要说明一下hook的方法,apects对hook有了很好的封装,第一参数是需要hook的SEL,第二个参数是一个枚举状态,表示你所hook得方法与第三个参数(block)的执行顺序,具体可以参见枚举说明。第三个block参数中可以获取到info,通过 [info instance]可以获取到调用的实例对象,在这里是个button。

btn.buriedPointTag的属性是专门用来处理统计的按钮的标签,当然你也可以用原生的tag标签,我这里主要是为了完全抽离这里的逻辑。

以下是为button添加buriedPointTag的方法

- (NSString *)buriedPointTag

{

return objc_getAssociatedObject(self, UIButton_buriedPoint_key);

}

- (void)setBuriedPointTag:(NSString *)buriedPointTag

{

objc_setAssociatedObject(self, UIButton_buriedPoint_key, buriedPointTag, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

这样就轻松的把按钮的统计做好,当然你的产品要对别的控制也做统计,你仍然需要去额外处理,你也可以用这种方法对别的类型的统计业务进行抽离,具体情况需要看需求有没有必要这么处理。

时间: 2024-10-07 06:59:33

iOS中AOP与Method Swizzling 项目中的应用的相关文章

ios逆向工程-内部钩子(Method Swizzling)

Method Swizzling(方法调配) 怎么说呢,先了解什么是钩子为什么用钩子,学过C++的朋友应该清楚,hook就是用来获得(截断/改变)底层调用的方法.这样我们可以自由的修改或者读取一些想要的东西.(个人理解) 下面是百度百科的解释:钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的.当消息到达后,在目标窗口处理函数之前处理它.钩子机制允许应用程序截获处理window消息或特定事件 那io

poi在java中可用,在web项目中不可用

Servlet.service() for servlet [servlets.Upload] in context with path [/Excel] threw exception [Servlet execution threw an exception] with root cause java.lang.ClassNotFoundException: org.apache.poi.xssf.usermodel.XSSFWorkbook 在main函数里面和web里面不太一样 web要

【Vue中的坑】vue项目中动态绑定src不显示图片解决方法

v-for绑定src的数据如下: data() { return { img_src:"../../assets/images/mirror-service.png" } } 渲染之后,发现图片不显示,上网查找之后发现是应为图片链接是需要通过 require包裹的 data() { return { img_src:require("../../assets/images/mirror-service.png)" } } 然后就会发现好使了 原文地址:https:/

Method Swizzling 和 AOP 实践(转)

上一篇介绍了 Objective-C Messaging.利用 Objective-C 的 Runtime 特性,我们可以给语言做扩展,帮助解决项目开发中的一些设计和技术问题.这一篇,我们来探索一些利用 Objective-C Runtime 的黑色技巧.这些技巧中最具争议的或许就是 Method Swizzling . 介绍一个技巧,最好的方式就是提出具体的需求,然后用它跟其他的解决方法做比较. 所以,先来看看我们的需求:对 App 的用户行为进行追踪和分析.简单说,就是当用户看到某个 Vie

ios method swizzling

阅读器 iOS开发iOS 本文由TracyYih[博客]翻译自NSHipster的文章Method Swizzling. 在上周associated objects一文中,我们开始探索Objective-C运行时的一些黑魔法.本周我们继续前行,来讨论可能是最受争议的运行时技术:method swizzling. Method swizzling指的是改变一个已存在的选择器对应的实现的过程,它依赖于Objectvie-C中方法的调用能够在运行时进改变——通过改变类的调度表(dispatch tab

项目中js调用service和procedure的办法

Ajax.js 1 /**通用ajax服务的定义对象 2 3 * services可以是单个服务对象,也可以是service服务数组 4 * 具体服务的定义请参考appendServices成员函数 5 */ 6 function Service(services){ 7 this.services=[]; 8 this.shareParameters={}; 9 /**添加共享参数,在这里统一设置共享参数 10 */ 11 this.addShareParameters=function(sh

GT手机性能测试工具二:项目中配置

GT demo官方示例文档 http://gt.qq.com/docs/i/GTiOSUserGuide.pdf 云笔记中实践GT过程 云笔记项目中嵌入GT framework: step1 下载framework SDK 下载地址 http://gt.qq.com/download.html iOS平台 最新release版是 v2.2.3,发布日期是2015年8月26日. GT SDK: GT.embeddedframework_v2.2.3.tar.gz 将framework下载至本地目录

(十)android项目中,通用布局的对话框的实现。

在工作中,我们的APP项目中经常需要用到dialog,一般设计师对于一个APP项目,会设计使用同一个风格,显示不同内容的对话框,所以为了提高开发的效率,我们可以针对一个项目设计一个通用的对话框,所有用到的地方都可以调用.本文针对下面效果的对话框,实现了一个通用对话框,具体实现核心代码如下所示. 1 CustomDialog.java代码实现如下所示: import android.app.ActionBar.LayoutParams; import android.app.Dialog; imp

JavaWeb 项目中的绝对路径和相对路径以及问题的解决方案

最近在做JavaWeb项目,总是出现各种的路径错误,而且发现不同情况下 /  所代表的含义不同,导致在调试路径上浪费了大量时间. 在JavaWeb项目中尽量使用绝对路径  因为使用绝对路径是绝对不会出错的,而使用相对路径可能会出现错误. 首先 说下在JavaWeb项目中的绝对路径和相对路径的含义 绝对路径: 相对于当前Web应用根路径的路径  也就是任何路径都必须要带上contextPath =  http://localhost:8080/WebProject/ 相对路径: 相对于当前目录的路