代码改变世界

iOS中使用NSInvocation

2017-05-11 15:20  Hi,David  阅读(309)  评论(0编辑  收藏  举报

在iOS中可以使用NSInvocation进行动态调用方法。

/*
NSInvocation is much slower than objc_msgSend()...
Do not use it if you have performance issues.
*/

 

ViewController.h

#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end

ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    //1.创建 NSMethodSignature
    NSMethodSignature *sig = [self methodSignatureForSelector:@selector(sendMessageWithStr1:andStr2:andStr3:)];
    if (!sig) {
        [self doesNotRecognizeSelector:@selector(sendMessageWithStr1:andStr2:andStr3:)];
        return;
    }
    
    //2.根据 NSMethodSignature 创建 NSInvocation
    NSInvocation *inv = [NSInvocation invocationWithMethodSignature:sig];
    if (!inv) {
        [self doesNotRecognizeSelector:@selector(sendMessageWithStr1:andStr2:andStr3:)];
        return;
    }
    
    //3.设置代理和Selector
    [inv setTarget:self];
    [inv setSelector:@selector(sendMessageWithStr1:andStr2:andStr3:)];
    
    //4.设置参数
    NSString *str1 = @"111";
    NSString *str2 = @"222";
    NSString *str3 = @"333";
    
    //注意:设置参数的索引时不能从0开始,因为0已经被self占用,1已经被_cmd占用,可变参数可以使用va_list和va_start,具体参考参考YYKit中的NSObject+YYAdd.m
    [inv setArgument:&str1 atIndex:2];
    [inv setArgument:&str2 atIndex:3];
    [inv setArgument:&str3 atIndex:4];
    
    //5.调用方法
    [inv invoke];
}

- (void)sendMessageWithStr1:(NSString *)str1 andStr2:(NSString *)str2 andStr3:(NSString *)str3{
    NSLog(@"str1:%@,str2:%@,str3:%@",str1,str2,str3);
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

运行截图:

 

参考文章:

http://www.jianshu.com/p/da96980648b6