Aspects 原理简析
Aspects 是使用 Objective-C 语言编写的 AOP 库。在此简单的记录一下原理简析,备忘。
简述
下文中,selector 指开发者想 hook 的方法,block 指开发者想执行的代码
aspect_add
保存所有开发者需要执行的 block 到 容器中
执行 aspect_prepareClassAndHookSelectoraspect_prepareClassAndHookSelector
动态创建子类:aspect_hookClass
给 selector 起了一个别名(添加了前缀 Aspects__),并将 selector 的 imp 指向了 Aspects__selector
将 _objc_msgForward/_objc_msgForward_stret 的 imp 指向了 selectoraspect_hookClass
动态生成子类
交换方法 aspect_swizzleForwardInvocationaspect_swizzleForwardInvocation
将 forwardInvocation: 的 IMP 指向了 Aspects 自定义的 IMP __ASPECTS_ARE_BEING_CALLED____ASPECTS_ARE_BEING_CALLED__
根据参数 invocation ,获得 selector ,拿到 aliasSelector(即:Aspects__selector) ,根据 aliasSelector 拿到 selector 的 IMP
从容器中取出所有的 before instead after 的 block,按照顺序,依次执行,没有 instead 的 block ,就执行 aliasSelector。执行
执行代码,当调用 selector 时,其 imp 是 _objc_msgForward/_objc_msgForward_stret ,直接触发了 forwardInvocation: ,此时 forwardInvocation: 的 imp 指向的是自定义的 __ASPECTS_ARE_BEING_CALLED__ ,在其内执行了 block
入口方法
1 | + (id<AspectToken>)aspect_hookSelector:(SEL)selector |
aspect_add
1 | static id aspect_add(id self, SEL selector, AspectOptions options, id block, NSError **error) { |
aspect_prepareClassAndHookSelector
1 | static void aspect_prepareClassAndHookSelector(NSObject *self, SEL selector, NSError **error) { |
aspect_hookClass
1 | static Class aspect_hookClass(NSObject *self, NSError **error) { |
aspect_swizzleForwardInvocation
1 | static NSString *const AspectsForwardInvocationSelectorName = @"__aspects_forwardInvocation:"; |
__ASPECTS_ARE_BEING_CALLED__
1 | static void __ASPECTS_ARE_BEING_CALLED__(__unsafe_unretained NSObject *self, SEL selector, NSInvocation *invocation) { |
Aspects 原理简析