前言
众所周知,Aspects框架运用了AOP(面向切面编程)的思想,这里解释下AOP的思想:AOP是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。也许大家用Aspects提供的两个方法用着很爽,有没有想揭开它的神秘面纱,看一下它的庐山真面目?接下来主要讲下Aspects的主要实现原理。
ruhua.gif
实现原理
其实主要涉及到两点,用过runtime的同学都知道swizzling
和消息转发,如果还不是很清楚的同学可以看下我之前写的一篇文章OC中swizzling的“移魂大法”,“移魂大法”我这边就不累赘了,提下消息转发。
消息转发
MessageForward.jpg
当向一个对象发送消息的时候,在这个对象的类继承体系中没有找到该方法的时候,就会Crash掉,抛出* unrecognized selector sent to …
异常信息,但是在抛出这个异常前其实还是可以拯救的,Crash之前会依次执行下面的方法:
resolveInstanceMethod
(或resolveClassMethod
):实现该方法,可以通过class_addMethod
添加方法,返回YES的话系统在运行时就会重新启动一次消息发送的过程,NO的话会继续执行下一个方法。
2.forwardingTargetForSelector
:实现该方法可以将消息转发给其他对象,只要这个方法返回的不是nil或self,也会重启消息发送的过程,把这消息转发给其他对象来处理。
-
methodSignatureForSelector
:会去获取一个方法签名,如果没有获取到的话就回直接挑用doesNotRecognizeSelector
,如果能获取的话系统就会创建一个NSlnvocation
传给forwardInvocation
方法。 -
forwardInvocation
:该方法是上一个步传进来的NSlnvocation
,然后调用NSlnvocation
的invokeWithTarget
方法,转发到对应的Target
。 -
doesNotRecognizeSelector
:抛出unrecognized selector sent to …
异常。
整体原理
上面讲了几种消息转发的方法,Aspects
主要是利用了forwardInvocation
进行转发,Aspects
其实利用和kvo
类似的原理,通过动态创建子类的方式,把对应的对象isa指针指向创建的子类,然后把子类的forwardInvocation
的IMP
替成__ASPECTS_ARE_BEING_CALLED__
,假设要hook
的方法名XX