Aspects--iOS的AOP(面向切面编程)库

最近项目需要用到友盟统计,统计埋点大概有四五十个,一开始想到的是在项目中找到各个统计事件触发的位置,然后在后面加上友盟统计的代码。友盟官方SDK的说明也是这么干,在需要统计的地方加上统计的代码就可以了,看起来非常的简单。但是考虑到以后维护的问题,就显得有点蛋疼了,比如,以后不再使用友盟而更换其他统计框架、需要新增或删除统计埋点,又得到处增删改查了。大神同事推荐了一个框架--Aspects,很好的解决了这个问题。所有统计代码可以放在一个方法里面,应用启动的时候初始化一遍就ok了!
网上已经有的东西文中直接给出链接,本文主要内容在于介绍一下使用Aspects遇到的几个坑和解决方法。

一、什么是AOP

一句话概括:可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。
AOP 百度百科

二、关于Aspects

它是一个使iOS支持AOP面向切面编程的库,可以在不改变类或者对象行为的情况下给类或者对象添加代码。你可以在方法执行前/后或者替代原方法执行一段你想执行的代码。你可以认为Aspects是一种method swizzling,但是它比method swizzling简单易用。

项目地址:Aspects
关于使用:直接阅读README文件。
网络资源:Aspects iOS的AOP面向切面编程的库,翻译较老,错误也多,可以参考。

三、遇到的问题及解决方案

1、当你给某个类添加钩子时(使用类方法),不能同时hook父类和子类的同一个方法;
解决方法1:在某些情况下(自定义类并自定义方法),可以考虑重构一下同名的方法,申明一个不同名的方法,在该方法内部重新调用一下同名方法。
解决方法2:定义一个空的方法,不需要任何实现,在需要hook的方法里面调用一下,当然Aspects需要hook这个新定义的方法;

2、不能重复hook同一个类的子类对象的同名方法;
解决方法:重构同名方法,举例说明:
有两个继承自UITableViewController的类,都需要hook他们的tableView:didSelectRowAtIndexPath:方法,那么可以把其中一个tableView:didSelectRowAtIndexPath:改写一下:
声明:
- (void)AspectsHookTableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
实现:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

[self AspectsHookTableView:tableView didSelectRowAtIndexPath:indexPath];

};
- (void)AspectsHookTableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

//本来在tableView:didSelectRowAtIndexPath:方法中实现的代码放到这里

}

3、无法hook一个对象的私有方法。
解决方法:将对象的私有方法公开申明一下,对于协议方法也有效。

你可能感兴趣的:(Aspects--iOS的AOP(面向切面编程)库)