NSInvocation

在iOS开发中,我们一般会使用以下两种方式去调用一个方法

(1) [obj methodName];
(2) [obj performSelector......];

为什么使用方法2 ?看下面需求 方式一不能通过方法名字符串来执行方法

需求1.:通过字符串调用方法

    NSString *str = @"invocationThisMethord:";
    [self performSelector:NSSelectorFromString(str) withObject:@"name" afterDelay:0];

- (void)invocationThisMethord:(NSString *)name {
    NSLog(@"invocationThisMethord %@",name);
}
 完美解决需求

需求2.:通过字符串调用下面方法

//方法名字符串
NSString *methodNameStr = @"test:withArg2:andArg3:";

我们知道[obj performSelector......]; 参数有限  怎么办?

所以我们就需要用到了NSInvocation
       //1.创建一个方法签名
    NSMethodSignature *signature = [self methodSignatureForSelector:NSSelectorFromString(methodNameStr)];
    //2.使用方法的签名来创建一个NSInvocation对象
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    //3.给invocation的两个属性赋值 要执行谁的(target)的哪个方法(selector)
    invocation.target = self;
    invocation.selector = NSSelectorFromString(methodNameStr);
    
    //4.给要执行的方法设置参数 使用setArgument:atIndex:方法给要执行的方法设置参数,注意下标从2开始,因为0、1已经被target与selector占用
    NSString *param1 = @"param1";
    NSString *param2 = @"param2";
    NSString *param3 = @"param3";
    [invocation setArgument:¶m1 atIndex:2];
    [invocation setArgument:¶m2 atIndex:3];
    [invocation setArgument:¶m3 atIndex:4];
    //5.执行方法
    [invocation invoke];

需求3.:通过字符串调用下面方法

NSString *methodNameStr = @"test:withArg2:andArg3:";
//要执行的方法
- (NSString *)test:(NSString *)arg1 withArg2:(NSString *)arg2 andArg3:(NSString *)arg3 {
    NSLog(@"%@---%@---%@", arg1, arg2, arg3);
}

    NSString *methodNameStr = @"test:withArg2:andArg3:";
    
    NSMethodSignature *signature = [self methodSignatureForSelector:NSSelectorFromString(methodNameStr)];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    invocation.target = self;
    invocation.selector = NSSelectorFromString(methodNameStr);
    
    NSString *param1 = @"param1";
    NSString *param2 = @"param2";
    NSString *param3 = @"param3";
    [invocation setArgument:¶m1 atIndex:2];
    [invocation setArgument:¶m2 atIndex:3];
    [invocation setArgument:¶m3 atIndex:4];
    [invocation invoke];
    
    if (signature.methodReturnLength > 0) {
        NSString *result;
        [invocation getReturnValue:&result];
        NSLog(@"%@",result);
    }

2019-01-18 17:48:41.350282+0800 Test[13957:7661495] param1---param2---param3
2019-01-18 17:48:41.350437+0800 Test[13957:7661495] lalallallala

你可能感兴趣的:(NSInvocation)