NSInvocation及NSMethodSignature的使用

NSInvocation为了解决performSelector...最多只能带“两个”参数的问题。

- (void)invocationDemo {
//    [self performSelector:@selector(invocationDemoWithValue:value2:value3:) withObject:@"" withObject:@""];
    
// 签名方法,selector的方法可以不是要调用的方法,但是参数个数必须相同。也可以使用类方法创建NSMethodSignature实例。
    NSMethodSignature *signature = [self methodSignatureForSelector:@selector(invocationDemoWithValue1:value2:value3:)];
    
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    NSString *string2 = @"--|";
    NSString *string3 = @"---|";
    NSString *string4 = @"----|";
// 必须从2开始,0、1已经被target、selector占用
    [invocation setArgument:&string2 atIndex:2];
    [invocation setArgument:&string3 atIndex:3];
    [invocation setArgument:&string4 atIndex:4];
    invocation.target = self;
    invocation.selector = @selector(invocationDemoWithValue1:value2:value3:);
    
    [invocation invoke];
    
// 返回值必须__weak修饰,否则会崩溃。
// 返回值为对象时,arc情况下容易出现崩溃问题,arc下vc如果用strong的,默认NSInvocation实现认为,已经对返回对象retain一次,实际上并没有,当返回对象出了作用域的事就就被收回,导致崩溃 返回值加个__weak 就可以了
    __weak NSString *returnString;
    [invocation getReturnValue:&returnString];
    
    NSLog(@"returnString:%@", returnString);
    
}
- (NSString *)invocationDemoWithValue1:(NSString *)value1 value2:(NSString *)value2 value3:(NSString*)value3 {
    
    return [NSString stringWithFormat:@"%@%@%@", value1, value2, value3];
}

补充:看到许多开源的代码,在Runtime中,这个类用的挺多。例如消息的转发。

你可能感兴趣的:(NSInvocation及NSMethodSignature的使用)