美文网首页
NSInvocation的使用

NSInvocation的使用

作者: heart_领 | 来源:发表于2018-06-24 17:22 被阅读7次

在iOS中方法调用的方式:
第一种方式

  • (id)performSelector:(SEL)aSelector;
  • (id)performSelector:(SEL)aSelector withObject:(id)object;
  • (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
    第二种方式
    NSInvocation
    如果参数多于两个,比较适合使用第二种方式
#import "ViewController.h"
#import <objc/message.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
//    方法签名
    //初始化NSMethodSignature
//    1.类方法 NSObject中的方法
//    NSMethodSignature *signature = [ViewController instanceMethodSignatureForSelector:@selector(run1:eat:)];//方法有两个参数
//   2.对象方法 NSObject中的方法
    NSMethodSignature *signature1 = [self methodSignatureForSelector:@selector(eatFood)];//方法有一个参数
//    3.类方法 NSMethodSignature中的方法
        NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:"v@:@"];//此处设置了一个参数
    //此时我们应该判断方法是否存在,如果不存在这抛出异常
    if (signature == nil) {
        //aSelector为传进来的方法
        NSString *info = [NSString stringWithFormat:@"%@方法找不到", NSStringFromSelector(@selector(run:))];
        [NSException raise:@"方法调用出现异常" format:info, nil];
    }
//    根据方法签名来创建NSInvocation对象
    //2、创建NSInvocation对象
    NSInvocation *invocaton = [NSInvocation invocationWithMethodSignature:signature];
//    设置方法调用者
    invocaton.target =self;
//    设置要调用的方法
    invocaton.selector = @selector(run:);//这里的方法与签名的方法可以一致也可以不一致,不一致时会调用此处设置的方法(可以在此处修改方法)
    //numberOfArguments方法获取的参数个数,包含self和_cmd,减去2之后才是签名方法中需要的参数个数
    NSArray *objects = @[@"a",@"b",@"c"];
    NSUInteger argsCount = signature.numberOfArguments-2;//签名方法的参数个数
    NSUInteger arrCount = objects.count;
    NSUInteger count = MIN(arrCount, argsCount);
    for (int i = 0; i<count; i++) {
        id obj = objects[i];
//         判断需要设置的参数是否是NSNull, 如果是就设置为nil
        if ([obj isKindOfClass:[NSNull class]]) {
            obj = nil;
        }
        [invocaton setArgument:&obj atIndex:i +2];// 逐个设置参数
    }
//    这里的Index要从2开始,以为0跟1已经被占据了,分别是self(target),selector(_cmd)
//    [invocaton setArgument:&objects atIndex:2];//签名的方法要有参数,没有的话,会在此处崩溃,如果签名方法的参数是两个,此处设置一个参数,那么第二个参数为nil
//    NSString *jjj;
//    [invocaton getArgument:&jjj atIndex:2];//获得参数
//    id res = nil;
//    if (signature.methodReturnLength != 0) {//有返回值
//        //将返回值赋值给res
//        [invocaton getReturnValue:&res];//没有返回值时,调用此方法崩溃
//    }
    [invocaton invoke];//执行完方法后,在往下执行
//    NSInteger tag;
//    得到执行方法后的返回值
//    [invocaton getReturnValue:&tag];//如果执行的方法返回YES,tag为YES,返回NO,tag为NO
//    可以通过signature.methodReturnType获得返回的类型编码,从而可以推断返回值的具体类型
    const char *signa = signature.methodReturnType;
    NSUInteger length = signature.methodReturnLength;
    /**
     获得返回的类型编码,因此可以推断返回值的具体类型
     返回类型为void,signa=v length=0
     返回类型为NSString,signa=@ length=8
     返回类型为BOOL,signa=B  length=1
     */
//    if (tag)  {
        NSLog(@"我是贾红领%s**%lu",signa,(unsigned long)length);
//    }
}
-(BOOL )run2:(NSString *)method eat:(NSString *)eatStr
{
    NSLog(@"222:%@***%@",method,eatStr);
    return YES;
}
-(void)run1:(NSString *)method eat:(NSString *)eatStr
{
    NSLog(@"111:%@***%@",method,eatStr);
}
-(void)run:(NSString *)method
{
    NSLog(@"333%@",method);
}
-(void)eatFood
{
}

相关文章

  • NSInvocation个人理解

    NSInvocation的使用: //NSInvocation;用来包装方法和对应的对象,它可以存储方法的名称,对...

  • NSInvocation

    NSInvocation的基本使用 11 异常处理

  • NSInvocation 使用

    NSString*result1 = [selfappend:@"a"withStr2:@"b"andStr3:@...

  • NSInvocation使用

    NSInvocation NSInvocation是一个消息调用类,主要作用是存储和传递消息。它存储的信息包含了一...

  • NSInvocation的使用

    一、介绍 在 iOS中可以直接调用方法的方式有两种: 1、performSelector:withObject;2...

  • NSInvocation的使用

    在iOS中方法调用的方式:第一种方式 (id)performSelector:(SEL)aSelector; (i...

  • NSInvocation的使用

    背景 在最近的项目开发中遇到了一个很别扭的问题。项目本身是一个SDK,供业务方App集成使用。SDK内部有网络请求...

  • NSInvocation的使用

    NSInvocation的使用 1 生成需要调用方法的签名NSMethodSignature,使用根据调用的Sel...

  • NSInvocation的使用

    1.NSInvocation的作用 封装了方法调用对象、方法选择器、参数、返回值等,可以给对象发送一个参数大于两个...

  • NSInvocation的使用

    版本:iOS13.6 一、简介 通常调用方法的方式是使用[实例 方法名]或[实例 方法名:参数] 若该方法没有公开...

网友评论

      本文标题:NSInvocation的使用

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