objective-c - 使用反射/内省(introspection)调用参数数量未知的选择器

标签 objective-c ios reflection introspection

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

现在我需要为 iOS 实现相同的功能,当我知道选择器期望的参数数量时,我能够调用一个选择器,如下所示:

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

我知道我可以通过使用获取选择器接收的参数数量

int numberOfArguments = method_getNumberOfArguments(selector);

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

[someObject performSelector:selector withObject:arrayOfObjects]

这几乎等同于 Java 的

someMethod.invoke(someObject, argumentsArray[]);

?

我想根据选择器获得的参数数量来避免 switch case。

抱歉挖了这么久,我只是想让我的问题尽可能清楚。

最佳答案

这个小函数应该可以解决问题,它并不完美,但它为您提供了一个起点:

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
}

关于objective-c - 使用反射/内省(introspection)调用参数数量未知的选择器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5788346/

相关文章:

iphone - 我怎样才能创建这个数据结构?

具有多个可见页面的 iOS UIScrollView

c++ - 如何将 wstring 转换为 NSString

iphone - 按下按钮时如何关闭 UISplitViewController

c# - 如何防止 MemberInfo.IsDefined 在不相关的属性上抛出 FileNotFoundException?

java - 如何使用 java 中的反射确定泛型类型的构造函数参数数量?

java - 从堆栈跟踪元素获取实际类

ios - CAPS 页面菜单 : willMoveToPage delegate method getting error

ios - 从不同的 Xcode 项目加载 Storyboard

ios - 以编程方式创建多个标签变量