1, 两个接口的差别
实例对象 --》 类型: 类
类对象 ---》 类型: 元类
元类对象 ---》 类型 : 元类
receive接受消息的对象类型不同.接受者是类,就走的加号方法,接收者是实例,就走的减号方法
self // ----aspect 实例方法, 影响当前实例,类的其它实例不影响
self.class // ----aspect 实例方法 , 影响整个类的其它实例
objc_getMetaClass(object_getClassName(self.class)) //才是aspect 类方法
object_getClass(self.class) //aspect 类方法
/// Adds a block of code before/instead/after the current `selector` for a specific class.
///
/// @param block Aspects replicates the type signature of the method being hooked.
/// The first parameter will be `id<AspectInfo>`, followed by all parameters of the method.
/// These parameters are optional and will be filled to match the block signature.
/// You can even use an empty block, or one that simple gets `id<AspectInfo>`.
///
/// @note Hooking static methods is not supported.
/// @return A token which allows to later deregister the aspect.
+ (id<AspectToken>)aspect_hookSelector:(SEL)selector
withOptions:(AspectOptions)options
usingBlock:(id)block
error:(NSError **)error;
/// Adds a block of code before/instead/after the current `selector` for a specific instance.
- (id<AspectToken>)aspect_hookSelector:(SEL)selector
withOptions:(AspectOptions)options
usingBlock:(id)block
error:(NSError **)error;
/// Deregister an aspect.
/// @return YES if deregistration is successful, otherwise NO.
id<AspectToken> aspect = ...;
[aspect remove];
2, hook方法的时机
Adds a block of code before/instead/after the current selector
for a specific class.
3, hook 方法
block
第一个参数是 id<AspectInfo> ,后面跟着原有方法的参数列表,并且方法个数相同,类型是匹配的(对象类型--匹配对象类型, 值类型匹配值类型)。
可以只传一个参数
可以不要参数
[self aspect_hookSelector:@selector(a1:a2:a3:a4:) withOptions:AspectPositionBefore usingBlock:^ (id<AspectInfo>info, NSString*a1,NSString*a2,int a,CGRect rect){
NSLog(@"%s [%d]",__func__,__LINE__);
} error:&error];
if (error) {
NSLog(@"%@",error);
}
[self a1:@"111111" a2:@"222222" a3:1213 a4:CGRectZero];
-(void)a1:(NSString*)a1 a2:(NSString*)a2 a3:(int)a3 a4:(CGRect)rect {
NSLog(@"%s [%d]",__func__,__LINE__);
}
4, 修改方法的返回值
You can use the invocation object to customize the return value:
[PSPDFDrawView aspect_hookSelector:@selector(shouldProcessTouches:withEvent:) withOptions:AspectPositionInstead usingBlock:^(id<AspectInfo> info, NSSet *touches, UIEvent *event) {
// Call original implementation.
BOOL processTouches;
NSInvocation *invocation = info.originalInvocation;
[invocation invoke];
[invocation getReturnValue:&processTouches];
if (processTouches) {
processTouches = pspdf_stylusShouldProcessTouches(touches, event);
[invocation setReturnValue:&processTouches];
}
} error:NULL];
网友评论