Objective C - 获取方法的参数类型? [英] Objective C - Get argument types of a method?

查看:109
本文介绍了Objective C - 获取方法的参数类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在运行时,我需要能够获取方法的参数类型.以下是打印出来的内容:

At runtime I need to be able to get the argument types of a method. The following is what gets printed:

我读过其他线程,在运行时目标 c 将传递给方法的所有对象视为 id 的参数.如果这种方法对读取参数类型的方法没有任何其他建议?

I have read on other threads that at run-time time objective c treats all objects passed to a method as arguments as id. If this approach doesn't work any other suggestions on a way to read argument types?

日志

2014-02-07 15:47:08.962 OCInjection[55727:70b] @
2014-02-07 15:47:08.964 OCInjection[55727:70b] :

代码

Class class = NSClassFromString(injectionBinding);

unsigned int methodCount;
Method *methodList = class_copyMethodList(class, &methodCount);

for (int i = 0; i < methodCount; i++)
{
   Method method = methodList[i];
   SEL selector = method_getName(method);
   NSMethodSignature *signature = [class instanceMethodSignatureForSelector:selector];

   NSUInteger numberOfArguments = [signature numberOfArguments];

   for (int i=0 ; i<numberOfArguments ; i++)
   {
      NSString *type = [NSString stringWithUTF8String:[signature getArgumentTypeAtIndex:i]];
                    NSLog(type);
   }
}

推荐答案

似乎不可能做到这一点.我最终使用代理对象将消息发送到并捕获它.可能不是理想的方式,但我还没有找到更好的解决方案.

Doesn't seem like it's possible to do this. I ended up using a proxy object to send the message to, and capture it. Probably not the ideal way, but I haven't found a better solution.

@interface DIContructorInjectorProxy()
@property (nonatomic, strong) id realObject;
@end

@implementation DIContructorInjectorProxy

#define Inject(x) [DIContructorInjectorProxy _injectMacro:x]

- (id)initWithClass:(Class)class
{
   self.realObject = [[class alloc] init];
}

+ (id)_injectMacro:(id)x
{
    if ([x isKindOfClass:NSClassFromString(@"Protocol")])
        return NSStringFromProtocol(x);
    else
        return NSStringFromClass(x);
}

- (id)withConstructor
{
    // Just making the method call for defining a constructor more readable by a call to this method first
    return self;
}

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
    NSMutableString *selectorName = [NSStringFromSelector(anInvocation.selector) mutableCopy];
    NSUInteger numberOfColonsInMethodName = [selectorName replaceOccurrencesOfString:@":"
                                                                           withString:@":"
                                                                              options:NSLiteralSearch
                                                                                range:NSMakeRange(0, selectorName.length)];

    [anInvocation retainArguments];
    NSMutableArray *argumentsPassedToSelector = [NSMutableArray array];

    for (int i=2 ; i<numberOfColonsInMethodName+2 ; i++)
    {
        NSString *argument;
        [anInvocation getArgument:&argument atIndex:i];
        [argumentsPassedToSelector addObject:[NSString stringWithFormat:@"%@", argument]];
    }

    // Store arguments somewhere

    return;
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
    return [self.realObject methodSignatureForSelector:aSelector];
}

@end

用户如何使用它来定义方法参数

How the user uses this to define method arguments

[self bindProtocol:@protocol(DataStorage) toClass:[InMemoryDataStorage class]];

// withConstructor returns an appropriate proxy object
// Then when the init method is called, it calls forwardInvocation, 
// and from there I save all the info I need about the method and arguments
(void)[[[self bindProtocol:@protocol(GoogleClient) toClass:[GoogleClientEngine class]] withConstructor]
                initWithDataStorage:Inject(@protocol(DataStorage))];

这篇关于Objective C - 获取方法的参数类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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