美文网首页
NSInvocation应用与理解

NSInvocation应用与理解

作者: lltree | 来源:发表于2018-06-08 15:46 被阅读32次

    NSMethodSignature 顾名思义应该就是“方法签名”,类似于C++中的编译器时的函数签名。苹果官方定义该类为对方法的参数、返回类似进行封装,协同NSInvocation实现消息转发。通过消息转发实现类似C++中的多重继承;

    NSMethodSignature 主要提供了一下功能:

    • 1、方法参数个数
    • 2、方法参数类型
    • 3、方法返回值类型

    签名方法的生成

    我们可以通过类的实例方法或者类方法获取该类下的(SEL)aSelector 的方法签名

    - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector OBJC_SWIFT_UNAVAILABLE("");
    
    + (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)aSelector OBJC_SWIFT_UNAVAILABLE("");
    

    通过实例获取某一个方法签名:

     NSMethodSignature* methodSig = [[[someClass alloc] init] methodSignatureForSelector:action];
    

    通过类获取某一个方法签名:

    NSMethodSignature *sig = [[someClass class] instanceMethodSignatureForSelector:myMethod];
    

    获取方法参数个数及类型

    NSUInteger argCount = [sig numberOfArguments];
       NSLog(@"argCount:%ld", argCount);
    
       for (NSInteger i=0; i<argCount; i++) {
           NSLog(@"%s", [sig getArgumentTypeAtIndex:i]);
       }
    
    作者:城市之光
    链接:https://www.jianshu.com/p/7e2efff789e2
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    

    获取方法签名的返回值类型

    并且我们可以通过

    @property (readonly) const char *methodReturnType NS_RETURNS_INNER_POINTER;
    

    从而完成

    #pragma mark - private methods
    - (id)safePerformAction:(SEL)action target:(NSObject *)target params:(NSDictionary *)params
    {
        NSMethodSignature* methodSig = [target methodSignatureForSelector:action];
        if(methodSig == nil) {
            return nil;
        }
        const char* retType = [methodSig methodReturnType];
        
     //返回void 类型
        if (strcmp(retType, @encode(void)) == 0) {
            NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
            [invocation setArgument:&params atIndex:2];
            [invocation setSelector:action];
            [invocation setTarget:target];
            [invocation invoke];
            return nil;
        }
        
    //返回NSInteger 类型
        if (strcmp(retType, @encode(NSInteger)) == 0) {
            NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
            [invocation setArgument:&params atIndex:2];
            [invocation setSelector:action];
            [invocation setTarget:target];
            [invocation invoke];
    
    //获取到方法返回值
            NSInteger result = 0;
            [invocation getReturnValue:&result];
            return @(result);
        }
        
        if (strcmp(retType, @encode(BOOL)) == 0) {
            NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
            [invocation setArgument:&params atIndex:2];
            [invocation setSelector:action];
            [invocation setTarget:target];
            [invocation invoke];
    //获取到方法返回值
            BOOL result = 0;
            [invocation getReturnValue:&result];
            return @(result);
        }
        
        if (strcmp(retType, @encode(CGFloat)) == 0) {
            NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
            [invocation setArgument:&params atIndex:2];
            [invocation setSelector:action];
            [invocation setTarget:target];
            [invocation invoke];
    //获取到方法返回值
            CGFloat result = 0;
            [invocation getReturnValue:&result];
            return @(result);
    
    
        }
        
        if (strcmp(retType, @encode(NSUInteger)) == 0) {
            NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig];
            [invocation setArgument:&params atIndex:2];
            [invocation setSelector:action];
            [invocation setTarget:target];
            [invocation invoke];
    
    //获取到方法返回值
            NSUInteger result = 0;
            [invocation getReturnValue:&result];
            return @(result);
        }
        
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
        return [target performSelector:action withObject:params];
    #pragma clang diagnostic pop
    }
    

    相关文章

      网友评论

          本文标题:NSInvocation应用与理解

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