使用反射/内省调用具有未知数量参数的选择器 [英] Calling a selector with unknown number of arguments using reflection / introspection

查看:105
本文介绍了使用反射/内省调用具有未知数量参数的选择器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我在java(for android)中编写了一个应用程序,它使用反射来调用某些对象的方法。参数号和类型是未知的,这意味着,我有一个统一的机制,它接收一个对象名,方法名和参数数组(使用JSON)并使用参数数组(Object [])调用指定对象上的指定方法填充了所需类型的参数)。

Lately I wrote an application in java (for android) which used reflection to invoke methods of some objects. The argument number and type was unknown, meaning, I had a unified mechanism that received an object name, method name and array of parameters (using JSON) and invoked the specified method on the specified object with an array of the arguments (Object[] filled with arguments of the required types).

现在我需要为iOS实现相同的功能,当我知道选择器的参数数量时,我能够调用选择器期望这样:

Now I need to implement the same for iOS, I was able to invoke a selector when I knew the number of parameters the selector expected for like this:

SEL selector = NSSelectorFromString(@"FooWithOneArg");
[view performSelectorInBackground:selector withObject:someArg];

我知道我可以使用

int numberOfArguments = method_getNumberOfArguments(selector);

但有没有办法像这样进行通用调用:

But is there a way to make a generic call like this:

[someObject performSelector:selector withObject:arrayOfObjects]

几乎相当于Java的

someMethod.invoke(someObject, argumentsArray[]);

我想避免根据选择器获得的参数数量来切换大小写。

I want to avoid a switch case according to the amount of arguments the selector gets.

对于长时间的挖掘感到抱歉,我只是想让我的问题尽可能清楚。

Sorry for the long dig, I just want to make my question as clear as possible.

推荐答案

这个小功能应该可以解决问题,它并不完美,但它给你一个起点:

This small function should do the trick, its not perfect, but it gives you a starting point:

void invokeSelector(id object, SEL selector, NSArray *arguments)
{
    Method method = class_getInstanceMethod([object class], selector);
    int argumentCount = method_getNumberOfArguments(method);

    if(argumentCount > [arguments count])
        return; // Not enough arguments in the array

    NSMethodSignature *signature = [object methodSignatureForSelector:selector];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    [invocation setTarget:object];
    [invocation setSelector:selector];

    for(int i=0; i<[arguments count]; i++)
    {
        id arg = [arguments objectAtIndex:i];
        [invocation setArgument:&arg atIndex:i+2]; // The first two arguments are the hidden arguments self and _cmd
    }

    [invocation invoke]; // Invoke the selector
}

这篇关于使用反射/内省调用具有未知数量参数的选择器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆