NSInvocation应用与理解

####叙述
iOS中可以直接调用某个对象的消息方式有2中,1.通过performSelector:withObject:函数可以直接调用这个消息。但是perform相关的这些函数,有一个局限性,其参数数量不能超过2个,否则要做很麻烦的处理,2.NSInvocation也是一种消息调用的方法,并且它的参数没有限制。这两种直接调用对象消息的方法,在iOS4.0之后,大多被block结构所取代,只有在很老的兼容性系统中才会使用,简单用法总结如下

#####NSInvocation的基本使用
我写成了NSObject的类别 主要是以下2个方法 你可以可以对你的需要进行衍生出你需要的 如没返回值 没参数 等等
1.类方法

+ (id)mh_dynamicExcuteSelector:(SEL)selector arguments:(id)arguments,...
{
    if ([self respondsToSelector:selector]) {
        //创建一个函数签名,这个签名可以是任意的,但需要注意,签名函数的参数数量要和调用的一致。
        NSMethodSignature *methodSignature = [self methodSignatureForSelector:selector];
        //通过签名初始化
        NSInvocation* inv = [NSInvocation invocationWithMethodSignature:methodSignature];
        //设置参数
        int index = 2;
        id arg;
        va_list args;
        va_start(args, arguments);
        if (arguments) {
            [inv setArgument:&arguments atIndex:index];
            index++;
        }
        while ((arg = va_arg(args, id))) {
            [inv setArgument:&arg atIndex:index];
            index++;
        }
        va_end(args);
        [inv retainArguments];
        //设置selecteor
        [inv setSelector:selector];
        //设置target
        [inv setTarget:self];
         //消息调用
        [inv invoke];
         //取这个返回值
        void *returnValue = NULL;
        [inv getReturnValue:&returnValue];
        return (__bridge id)returnValue;
    }
    return nil;
}

2.实例方法

- (id)mh_dynamicExcuteHasReturnValueWithMethodName:(NSString *)methodName arguments:(id)arguments,...
{
    void *returnValue = NULL;
    SEL selector = NSSelectorFromString(methodName);
    if ([self respondsToSelector:selector]) {
        NSInvocation* inv = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:selector]];
        int index = 2;
        id arg;
        va_list args;
        va_start(args, arguments);
        if (arguments) {
            [inv setArgument:&arguments atIndex:index];
            index++;
        }
        while ((arg = va_arg(args, id))) {
            [inv setArgument:&arg atIndex:index];
            index++;
        }
        va_end(args);
        [inv retainArguments];
        [inv setSelector:selector];
        [inv setTarget:self];
        [inv invoke];
        [inv getReturnValue:&returnValue];

    }
    return (__bridge id)returnValue;
}
最近的文章

iOS跳转系统设置

####跳转到APP的设置界面跳转事件 NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; if([[UIApplication sharedApplication] canOpenURL:u …

于 继续阅读
更早的文章

ios自带Emotion表情

##iOS 自定义emoji表情键盘 ####首先 ,想要获取系统的表情,要首先知道表情对应的UTF8 的编码方式 //将数字转为 func EMOJI_CODE_TO_SYMBOL(x:Int)-> Int { return ((((0x808080F0 | (x &am …

于 继续阅读