在运行时,我需要能够获取方法的参数类型。以下是打印的内容:
我已经读过其他线程,在运行时,objective c将传递给方法的所有对象视为id
的参数。如果这种方法在读取参数类型的方法上没有任何其他建议吗?
日志
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);
}
}
答案 0 :(得分:1)
根据 -getArgumentTypeAtIndex: 和 Decode Class from @encoded type string
我认为没有方法可以获得“真正的”参数类型。
答案 1 :(得分:0)
似乎不可能这样做。我最终使用代理对象将消息发送到并捕获它。可能不是理想的方式,但我还没有找到更好的解决方案。
@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
用户如何使用它来定义方法参数
[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))];