正常来讲想实现AOP,可以利用runtime的特性进行method swizzle,但Aspects就是造好的轮子,而且更好用,下面简述下Aspects的基本原理
runtime的消息转发机制
在OC中,所有的消息调用最后都会通过objc_msgSend()方法进行访问通过objc_msgSend()进行消息调用,为了加快执行速度,这个方法在runtime源码中是用汇编实现的
然后调用lookUpImpOrForward()方法,返回值是个IMP指针,如果查找到了调用函数的IMP,则进行方法的访问
如果没有查到对于方法的IMP指针,则进行消息转发机制
第一层转发:会调用resolveInstanceMethod:、resolveClassMethod:,这次转发是方法级别的,开发者可以动态添加方法进行补救
第二层转发:如果第一层转发仍然没有找到SEL,则会进行第二层转发,调用forwardingTargetForSelector:,可以把调用转发到另一个对象,这是类级别的转发,调用另一个类的相同的方法
第三层转发:如果第二层转发返回nil,则会进入这一层处理,这层会调用methodSignatureForSelector:、forwardInvocation:,这次是完整的消息转发,因为你可以返回方法签名、动态指定调用方法的Target类A的方法m被添加切面方法。
创建一个类A的子类B,并hook子类B的forwardInvocation:方法拦截消息转发,使forwardInvocation:的IMP指向事先准备好的__ASPECTS_ARE_BEING_CALLED__函数(后面简称ABC函数),block方法的执行就在ABC函数中
把类A的对象的isa指针指向B,这样就把消息的处理转发到类B上,类似KVO的机制,同时会更改class方法的IMP,把它指向类A的class方法,当外界调用class时获取的还是类A,并不知道中间类B的方法m,类B会直接把方法m的IMP指向_objc_msgForward()方法,这样当调用方法m时就会走消息转发流程,触发ABC函数
作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要,这是一个我的点击加入群聊iOS交流群:789143298 ,不管你是小白还是大牛欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!