1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| static void aspect_prepareClassAndHookSelector(NSObject *self, SEL selector, NSError **error) { /// 获取已经 hook 的 Class , 下面有分析这个函数 Class klass = aspect_hookClass(self, error); /// 拿出目标方法 Method 与 IMP Method targetMethod = class_getInstanceMethod(klass, selector); IMP targetMethodIMP = method_getImplementation(targetMethod); /// 获取目标方法的 typeEncoding const char *typeEncoding = method_getTypeEncoding(targetMethod); /// 构造一个新的方法名 SEL aliasSelector = aspect_aliasForSelector(selector); /// 添加一个新方法 aliasSelector ,方法实现是 targetMethodIMP __unused BOOL addedAlias = class_addMethod(klass, aliasSelector, method_getImplementation(targetMethod), typeEncoding); /// 将 Class 的目标 Selector 指向 _objc_msgForward class_replaceMethod(klass, selector, aspect_getMsgForwardIMP(self, selector), typeEncoding); }
/// hook class 并返回 static Class aspect_hookClass(NSObject *self, NSError **error) { /// 获取当前类 Class statedClass = self.class; Class baseClass = object_getClass(self); /// 获取当前类的名字 NSString *className = NSStringFromClass(baseClass); /// 构建一个新名字 const char *subclassName = [className stringByAppendingString:AspectsSubclassSuffix].UTF8String; /// 动态创建一个继承于 baseClass ,名字为 subclassName 的类 Class subclass = objc_allocateClassPair(baseClass, subclassName, 0);
/// 将消息转发方法 forwardInvocation: 指向 Aspects 的一个 C 函数 __ASPECTS_ARE_BEING_CALLED__ aspect_swizzleForwardInvocation(subclass);
/// aspect_hookedGetClass 会将第一个参数的类的 -(Class)class 方法替换成第二个参数类的 -(Class)class 方法 aspect_hookedGetClass(subclass, statedClass); aspect_hookedGetClass(object_getClass(subclass), statedClass);
/// 注册这个类,使其可以被使用 objc_registerClassPair(subclass);
/// 将 self 实例中的 isa 指针指向 subclass。也就是说 self 现在是 subclass 的实例了。 object_setClass(self, subclass); return subclass; }
static NSString *const AspectsForwardInvocationSelectorName = @"__aspects_forwardInvocation:"; static void aspect_swizzleForwardInvocation(Class klass) { /// 获取 forwardInvocation: 消息转发 IMP IMP originalImplementation = class_replaceMethod(klass, @selector(forwardInvocation:), (IMP)__ASPECTS_ARE_BEING_CALLED__, "v@:@"); if (originalImplementation) { /// 将 __ASPECTS_ARE_BEING_CALLED__ 替换掉 forwardInvocation: class_addMethod(klass, NSSelectorFromString(AspectsForwardInvocationSelectorName), originalImplementation, "v@:@"); } }
static void aspect_hookedGetClass(Class class, Class statedClass) { /// 这样替换 ,[class class] 返回的 Class 是 statedClass Method method = class_getInstanceMethod(class, @selector(class)); IMP newIMP = imp_implementationWithBlock(^(id self) { return statedClass; }); class_replaceMethod(class, @selector(class), newIMP, method_getTypeEncoding(method)); }
/// __ASPECTS_ARE_BEING_CALLED__ 作为全局消息转发中心 /// 由于当前目标方法实现已经被替换成 _objc_msgForward ,所以目标方法被调用时,会调用到 @selector(forwardInvocation:) /// __ASPECTS_ARE_BEING_CALLED__ 被调用时,获取到的参数和 @selector(forwardInvocation:) 一样 static void __ASPECTS_ARE_BEING_CALLED__(__unsafe_unretained NSObject *self, SEL selector, NSInvocation *invocation) { /// 获取当前方法 selector SEL originalSelector = invocation.selector; /// 获取 hook 后的 selector SEL aliasSelector = aspect_aliasForSelector(invocation.selector); /// selector 替换 invocation.selector = aliasSelector; /// 获取绑定的 AspectsContainer ,也就是用户传入的 block 信息 AspectsContainer *objectContainer = objc_getAssociatedObject(self, aliasSelector); AspectsContainer *classContainer = aspect_getContainerForClass(object_getClass(self), aliasSelector); AspectInfo *info = [[AspectInfo alloc] initWithInstance:self invocation:invocation]; NSArray *aspectsToRemove = nil;
/** aspect_invoke 是一个宏,用来执行用户传入的 block
#define aspect_invoke(aspects, info) \ for (AspectIdentifier *aspect in aspects) {\ [aspect invokeWithInfo:info];\ if (aspect.options & AspectOptionAutomaticRemoval) { \ aspectsToRemove = [aspectsToRemove?:@[] arrayByAddingObject:aspect]; \ } \ } */
/// 执行 Berfore 的实现 aspect_invoke(classContainer.beforeAspects, info); aspect_invoke(objectContainer.beforeAspects, info);
/// 替换实现 BOOL respondsToAlias = YES; if (objectContainer.insteadAspects.count || classContainer.insteadAspects.count) { aspect_invoke(classContainer.insteadAspects, info); aspect_invoke(objectContainer.insteadAspects, info); }else { Class klass = object_getClass(invocation.target); do { if ((respondsToAlias = [klass instancesRespondToSelector:aliasSelector])) { [invocation invoke]; break; } }while (!respondsToAlias && (klass = class_getSuperclass(klass))); }
/// 执行 After 的实现 aspect_invoke(classContainer.afterAspects, info); aspect_invoke(objectContainer.afterAspects, info);
/// 若找不到方法抛出异常 if (!respondsToAlias) { invocation.selector = originalSelector; SEL originalForwardInvocationSEL = NSSelectorFromString(AspectsForwardInvocationSelectorName); if ([self respondsToSelector:originalForwardInvocationSEL]) { ((void( *)(id, SEL, NSInvocation *))objc_msgSend)(self, originalForwardInvocationSEL, invocation); }else { [self doesNotRecognizeSelector:invocation.selector]; } }
[aspectsToRemove makeObjectsPerformSelector:@selector(remove)]; }
|