引子:项目中需要对按钮点击事件进行统计分析,现在项目中就是在按钮的响应代码中添加点击事件,非常繁琐。所以使用了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);

}

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

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

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

    Method Swizzling(方法调配) 怎么说呢,先了解什么是钩子为什么用钩子,学过C++的朋友应该清楚,hook就是用来获得(截断/改变)底层调用的方法.这样我们可以自由的修改或者读取一些想要 ...

  2. JS中的位操作在实际项目中的应用

    前言: Linux中的文件管理子系统的权限管理,想必大家都知道:rwx分别代表read(可读),write(可写), execute(可执行,如果是可执行程序的话),其中rxw可以按照数字表示: r  ...

  3. Eclipse中定位当前文件在项目中的位置

    点击红色框内的按钮,就能定位当前文件在项目中的位置, 另外, 找到位置后记得再点击一下这个按钮, 要不然每次打开一个文件都会自动定位

  4. idel 中 生成 jar包 和项目中自己需要的包

    一.首先在自己的项目中创建一个类类中创建一个构造方法构造方法中传入一个字符串参数(这个字符串参数是为了传入路径) 在方法体内通过file类创建文件夹(换而言之就是项目中的包) 二 .就是对这个项目中的 ...

  5. 项目中使用express,只是单纯项目中使用

    安装express npm install express --save-dv 建议安装到dev依赖里面 安装body-parse npm install body-parser --save-dev ...

  6. 使用AOP和Semaphore对项目中具体的某一个接口进行限流

    整体思路: 一 具体接口,可以自定义一个注解,配置限流量,然后对需要限流的方法加上注解即可! 二 容器初始化的时候扫描所有所有controller,并找出需要限流的接口方法,获取对应的限流量 三 使用 ...

  7. Eclipse中使用maven构建web项目中遇到的问题

    构建过程参考: http://blog.csdn.net/smilevt/article/details/8215558/ http://www.cnblogs.com/dcba1112/archiv ...

  8. 理解css中Grid布局,在项目中如何实现grid页面布局

    简介 CSS中Grid是一种二维网格式布局方式.我们常规使用table.float.position.inline-block等布局,但它们遗漏了很多功能,例如垂直居中.后来css3中flexbox的 ...

  9. 通过iframe引入另外一个项目中的html片段到项目中,解决样式,高度,兼容等问题的策略

     <!--尾部开始--> <iframe src="http://172.16.24.11:9000/cartoon-web/footer_new"    m ...

随机推荐

  1. iOS - 类簇

    类簇是在Objective-C中Foundation Framework中广泛使用的一种设计模式 1.发现类簇(Class Cluster)的踪迹 //*> 执行下面代码 id obj1 = [ ...

  2. django rest framework 入门

    django rest framework 入门1-序列化 Serialization 分类: Python 2013-01-22 22:24 11528人阅读 评论(0) 收藏 举报 djangop ...

  3. Nginx个人简单理解

    首先我们来补充下一些基本知识: 什么是代理服务器? 先举个简单的例子,现在我们在百度访问谷歌的网站,发现现在进不去,这个时候我们可以FQ(关于FQ,可以借鉴下这个博文:http://zhangge.n ...

  4. HBase基础和伪分布式安装配置

    一.HBase(NoSQL)的数据模型 1.1 表(table),是存储管理数据的. 1.2 行键(row key),类似于MySQL中的主键,行键是HBase表天然自带的,创建表时不需要指定 1.3 ...

  5. 在Nginx中部署基于IP的虚拟主机

    一.虚拟主机概念 虚拟主机是在网络服务器上划分出一定的磁盘空间供用户放置站点.应用组件等,提供必要的站点功能.数据存放和传输功能.所谓虚拟主机,也叫"网站空间", 就是把一台运行在 ...

  6. js007-函数表达式

    js007-函数表达式 本章内容 1.函数表达式的特征 2.使用函数实现递归 3.使用闭包定义私有量 定义函数的方式有两种:一:函数声明,二:函数表达式 函数声明: function function ...

  7. JS左右栏目添加器

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. JavaScript排序算法——插入排序

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. Codeforces 719B Anatoly and Cockroaches(元素的交叉排列问题)

    题目链接:http://codeforces.com/problemset/problem/719/B 题目大意: 有一队蟑螂用字符串表示,有黑色 ‘b’ 和红色 'r' 两种颜色,你想使这队蟑螂颜色 ...

  10. ast模块

    有这么一个需求,你想从文件中读取字典,方法有很多,这里用的是ast模块 import ast with open("account","r",encoding= ...