欢迎来到天天文库
浏览记录
ID:16106893
大小:346.49 KB
页数:64页
时间:2018-08-08
《aspects源码解析》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、Aspects源码解析 Adelightful,simplelibraryforaspectorientedprogramming 关键字:面向切片编程、OC动态性、消息转发、类型编码、Swizzle... 使用场景: 1.统一处理逻辑 2.在不改变源码的情况下,插入代码(如无侵染更改第三方库代码,干一些坏坏的事情) Aspects只有一个类文件,非常轻量级,在实现的思路上和JSPatch差不多。都主要用到OC的消息转发,最终都交给ForwardInvocation实现。二者很多地方有异曲同工之妙。 基本原理 我们知道OC是动态语言,我们执行一个函数的时候,其
2、实是在发一条消息:[receivermessage],这个过程就是根据message生成selector,然后根据selector寻找指向函数具体实现的指针IMP,然后找到真正的函数执行逻辑。这种处理流程给我们提供了动态性的可能,试想一下,如果在运行时,动态的改变了selector和IMP的对应关系,那么就能使得原来的[receivermessage]进入到新的函数实现了。 还是先来普及一下: OC上,每个类都是这样一个结构体: structobjc_class{ structobjc_class*isa; constchar*name; …. structob
3、jc_method_list**methodLists;/*方法链表*/ }; 其中methodList方法链表里存储的是Method类型: typedefstructobjc_method*Method; typedefstructobjc_method{ SELmethod_name; char*method_types; IMPmethod_imp; }; Method保存了一个方法的全部信息,包括SEL方法名,type各参数和返回值类型,IMP该方法具体实现的函数指针。 通过Selector调用方法时,会从methodList链表里找到对应Meth
4、od进行调用,这个methodList上的的元素是可以动态替换的,可以把某个Selector对应的函数指针IMP替换成新的,也可以拿到已有的某个Selector对应的函数指针IMP,让另一个Selector跟它对应,Runtime提供了一些接口做这些事。 比如: staticvoidviewDidLoadIMP(idslf,SELsel){ //CustomCode } Classcls=NSClassFromString(@"UIViewController"); SELselector=@selector(viewDidLoad); Methodmethod
5、=class_getInstanceMethod(cls,selector); //获得viewDidLoad方法的函数指针 IMPimp=method_getImplementation(method) //获得viewDidLoad方法的参数类型 char*typeDescription=(char*)method_getTypeEncoding(method); //新增一个ORIGViewDidLoad方法,指向原来的viewDidLoad实现 class_addMethod(cls,@selector(ORIGViewDidLoad),imp,typeD
6、escription); //把viewDidLoadIMP指向自定义新的实现 class_replaceMethod(cls,selector,viewDidLoadIMP,typeDescription); 这样就把UIViewController的-viewDidLoad方法给替换成我们自定义的方法,APP里调用UIViewController的viewDidLoad方法都会去到上述viewDidLoadIMP函数里,在这个新的IMP函数里调用新增的方法,就实现了替换viewDidLoad方法,同时为UIViewController新增了个方法-ORIGViewD
7、idLoad指向原来viewDidLoad的IMP,可以通过这个方法调用到原来的实现。 .Aspect要的是实现一个通用的IMP,任意方法任意参数都可以通过这个IMP中转。上面讲的都是针对某一个方法的替换,但如果这个方法有参数,怎样把参数值传给我们新的IMP函数呢?例如UIViewController的-viewDidAppear:方法,调用者会传一个Bool值,我们需要在自己实现的IMP(上述的viewDidLoadIMP)上拿到这个值,怎样能拿到?如果只是针对一个方法写IMP,是可以直接拿到这个参
此文档下载收益归作者所有