一个实例对象可以通过4种方式调用其方法。

2018/8/30 posted in  iOS
- (void)test{
    
//type1
    [self printStr1:@"hello world 1"];
    
//type2
    [self performSelector:@selector(printStr1:) withObject:@"hello world 2"];
    
//type3
    //获取方法签名
    NSMethodSignature *sigOfPrintStr = [self methodSignatureForSelector:@selector(printStr1:)];
    
    //获取方法签名对应的invocation
    NSInvocation *invocationOfPrintStr = [NSInvocation invocationWithMethodSignature:sigOfPrintStr];
    
    /**
    设置消息接受者,与[invocationOfPrintStr setArgument:(__bridge void * _Nonnull)(self) atIndex:0]等价
    */
    [invocationOfPrintStr setTarget:self];
    
    /**设置要执行的selector。与[invocationOfPrintStr setArgument:@selector(printStr1:) atIndex:1] 等价*/
    [invocationOfPrintStr setSelector:@selector(printStr1:)];
    
    //设置参数 
    NSString *str = @"hello world 3";
    [invocationOfPrintStr setArgument:&str atIndex:2];
    
    //开始执行
    [invocationOfPrintStr invoke];
    
    //type4
    ((void (*)(id,SEL,NSString *, NSArray *, NSInteger))objc_msgSend)(self, @selector(textFunctionWithParam:param2:param3:),@"111",@[@2,@3],123);

}
-(void)textFunctionWithParam:(NSString *)param1 param2:(NSArray *)param2 param3:(NSInteger)param3 {
    NSLog(@"param1:%@, param2:%@, param3:%ld",param1, param2, param3);
}
- (void)printStr1:(NSString*)str{
    NSLog(@"printStr1  %@",str);
}


下面展示block 的两种调用方式

- (void)test{

    void (^block1)(int) = ^(int a){
         NSLog(@"block1 %d",a);
    };
    
    //type1
    block1(1);
    
    //type2
    //获取block类型对应的方法签名。
    NSMethodSignature *signature = aspect_blockMethodSignature(block1);
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    [invocation setTarget:block1];
    int a=2;
    [invocation setArgument:&a atIndex:1];
    [invocation invoke];
}