美文网首页
Aspects 源码分析

Aspects 源码分析

作者: 唐tttyyy | 来源:发表于2020-04-12 13:34 被阅读0次

Aspects

分析- (id<AspectToken>)aspect_hookSelector:(SEL)selector                      withOptions:(AspectOptions)options                       usingBlock:(id)block                            error:(NSError **)error 

aspect_add:主要步骤

自旋锁执行下面hook操作,

1.取出AspectsContainer 对像,通过关联对象存储的值。

2.通过传入的selector,obj,block,等参数初始化AspectIdentifier,将AspectIdentifier 添加到AspectsContainer数组中去。

3.执行aspect_prepareClassAndHookSelector(self, selector, error);这个方法主要去给对象添加一个子类或者给类hook forwarding方法。后面详细分析aspect_prepareClassAndHookSelector的具体分析,

aspect_add代码如下:

中间类代码:

里面涉及到的中间类分析

1.AspectIdentifier 这个是每个hook 保存的aspect ,包含selector,block,blockSignature,object,options,其中blockSignature这个很重要,用到结构体去对应block,通过指针偏移查找到blockSignature,结构体代码如下:

2.AspectsContainer 这个类是用来保存所有的AspectIdentifier//Tracks all aspects for an object/class,,有三种数组beforeAspects,insteadAspects,afterAspects,(copy,atomic)属性。

3.AspectTracker 这个是打上标志的类,如果当前类已经hook了一个类方法,这个类及其父类都会保存selectorName,下次hook直接判断,不能再hook。

aspect_prepareClassAndHookSelector的具体分析代码如下:

1.aspect_hookClass的主要作用判断是否有后缀AspectsSubclassSuffix,说明之前hook过这个对象,中间类已经生成,判断是否元类,或者kvo之类的有过中间类,这2种情况直接aspect_swizzleForwardInvocation(klass); 就是__ASPECTS_ARE_BEING_CALLED__与 forwardInvocation进行方法交换。static NSString *const AspectsForwardInvocationSelectorName = @"__aspects_forwardInvocation:"; 这个AspectsForwardInvocationSelectorName对应原来的forwardInvocation的IMP

 IMP originalImplementation = class_replaceMethod(klass, @selector(forwardInvocation:), (IMP)__ASPECTS_ARE_BEING_CALLED__, "v@:@");

if (originalImplementation) {class_addMethod(klass,         NSSelectorFromString(AspectsForwardInvocationSelectorName), originalImplementation, "v@:@");}

如果没有hook过的对象,则创建中间类objc_allocateClassPair,objc_registerClassPair,aspect_hookedGetClass重定向class方法,使子类对象class方法返回base类对象,隐藏子类 aspect_hookedGetClass(subclass, statedClass) ,同时对forwardInvocation也进行方法交换

2.aspect_isMsgForwardIMP(targetMethodIMP) 判断原来selector 的IMP 是否是_objc_msgForward,如果没有,就新增一个带有AspectsMessagePrefix前缀的方法,并指向原seletor的IMP,原来seletor的imp指向!defined(__arm64__) ?_objc_msgForward :_objc_msgForward_stret这样最终方法都会走消息转发_objc_msgForward,最后会走到__ASPECTS_ARE_BEING_CALLED__

__ASPECTS_ARE_BEING_CALLED__的详细分析代码


1. AspectInfo *info = [[AspectInfo alloc] initWithInstance:self invocation:invocation];初始化一个AspectInfo对象,这个对象包含调用者和invocationaspect_invoke(aspects, info) 这个从AspectsContainer 当中的三个数组,去调度 这个info

具体核心调用代码如下:

1.用identirefier里的blocksign 去初始化一个调度者NSInvocation *blockInvocation = [NSInvocation invocationWithMethodSignature:self.blockSignature],从传入的info信息里面拿到NSInvocation *originalInvocation = info.originalInvocation,对比2个调度者参数信息,如果不一致返回NO,报错,然后从第二个参数开始遍历originalInvocation的参数传入到 blockInvocation,[originalInvocation getArgument:argBuf atIndex:idx];[blockInvocation setArgument:argBuf atIndex:idx];

最后设置blockInvocation的target,并invoke,[blockInvocation invokeWithTarget:self.block]这就是block的调用。依次执行classContainer.beforeAspects , classContainer.insteadAspects , classContainer.afterAspects重的block,如果是AspectPositionInstead的会替换aliasSelector的执行。

相关文章

  • iOS 引入 Aspects 吧,迟早会用到!

    引入 Aspects 吧,迟早会用到! 关于 AOP 在 iOS 中的应用,以及 Aspects 的源码分析文章...

  • Aspects 源码分析

    Method Swizzling 和 AOP 实践 这里唯一可能需要解释的是 class_addMethod 。要...

  • Aspects源码分析

    Aspects一直在项目中使用,主要使用AOP方式进行tracking,但还没好好看一看,最近研究了一下源码,十分...

  • Aspects 源码分析

    Aspects 分析- (id)aspect_hookSelector:(SEL)sel...

  • Aspects 源码分析

    需求 hook 实例对象的方法(仅该对象的方法被hook) hook 类对象的方法(该类所有对象调用该方法的时候,...

  • IOS中AOP框架Aspects源码分析

    IOS中AOP框架Aspects源码分析 AOP是Aspect Oriented Programming的缩写,意...

  • Aspects源码浅析

    Aspects源码浅析 同步发布到博客地址Aspects源码浅析 Aspects 可以很方便的让我们 hook 要...

  • Aspects源码解析

    Aspects 源码:https://github.com/steipete/Aspects 基本概述,此框架提供...

  • Aspects 源码解读

    Aspects 源码解读 1.Aspects简介 Aspects是一种面向切面编程,相对于继承而已,无需改动目标源...

  • Aspects改进尝试

    背景 一个库:Aspects两篇文章:面向切面编程之 Aspects 源码解析及应用消息转发机制与Aspects源...

网友评论

      本文标题:Aspects 源码分析

      本文链接:https://www.haomeiwen.com/subject/dubvmhtx.html