Aspects 库学习笔记

2018-06-13  本文已影响52人  我是小胡胡分胡

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];

上一篇下一篇

猜你喜欢

热点阅读