方法替换
Aspects
Aspects 是一个基于 Method Swizzle 的函数替换的第三方库,支持在方法执行前(AspectPositionBefore)/执行后(AspectPositionAfter)或替代原方法执行(AspectPositionInstead)
使用
- HOOK一个类的所有实例的指定方法
1 2 3 4 5 6 7 8 9 10 11 12 13
/// 为一个指定的类的某个方法执行前/替换/后,添加一段代码块.对这个类的所有对象都会起作用. /// /// @param block 方法被添加钩子时,Aspectes会拷贝方法的签名信息. /// 第一个参数将会是 `id<AspectInfo>`,余下的参数是此被调用的方法的参数. /// 这些参数是可选的,并将被用于传递给block代码块对应位置的参数. /// 你甚至使用一个没有任何参数或只有一个`id<AspectInfo>`参数的block代码块. /// /// @注意 不支持给静态方法添加钩子. /// @return 返回一个唯一值,用于取消此钩子. + (id<AspectToken>)aspect_hookSelector:(SEL)selector withOptions:(AspectOptions)options usingBlock:(id)block error:(NSError **)error; - HOOK一个类实例的指定方法
1 2 3 4 5
/// 为一个指定的对象的某个方法执行前/替换/后,添加一段代码块.只作用于当前对象. - (id<AspectToken>)aspect_hookSelector:(SEL)selector withOptions:(AspectOptions)options usingBlock:(id)block error:(NSError **)error; - Example
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
+(void)Aspect { // 在类UIViewController所有的实例执行viewWillAppear:方法完毕后做一些事情 [UIViewController aspect_hookSelector:@selector(viewWillAppear:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info) { NSString *className = NSStringFromClass([[info instance] class]); NSLog(@"%@", className); } error:NULL]; // 在实例myVc执行viewWillAppear:方法完毕后做一些事情 UIViewController* myVc = [[UIViewController alloc] init]; [myVc aspect_hookSelector:@selector(viewWillAppear:) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info) { id instance = info.instance; //调用的实例对象 id invocation = info.originalInvocation; //原始的方法 id arguments = info.arguments; //参数 [invocation invoke]; //原始的方法,再次调用 } error:NULL]; // HOOK类方法 Class metalClass = objc_getMetaClass(NSStringFromClass(UIViewController.class).UTF8String); [metalClass aspect_hookSelector:@selector(ClassMethod) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> info) { NSLog(@"%@", HOOK类方法); } error:NULL]; }
本文由作者按照 CC BY 4.0 进行授权