Ожидайте, что тип аргумента будет целым, но вместо этого получите идентификатор
Я использую forwardInvocation:
особенность target-c и мне нужно знать, какой тип аргумента получил метод. В моем примере я передаю это int
но getArgumentTypeAtIndex:
говорит мне, что это id
вместо. Вот простой пример:
@interface Do : NSObject
+ (void) stuff:(int)x;
@end
@implementation Do
+ (NSMethodSignature *) methodSignatureForSelector:(SEL)selector
{
NSMethodSignature* signature = [super methodSignatureForSelector:selector];
if (!signature)
signature = [self methodSignatureForSelector:@selector(forwardInvocation:)];
return signature;
}
+ (void)forwardInvocation:(NSInvocation *)i
{
const char* argType = [i.methodSignature getArgumentTypeAtIndex:2];
NSLog(@"%s == %s", argType, @encode(id)); // @ == @
NSLog(@"%s == %s", argType, @encode(int)); // @ == i
}
@end
Вот как я это называю:
[Do stuff:123];
Любая идея, почему я не получаю id
вместо int
как тип?
2 ответа
Проблема в том, что у вас нет stuff:
метод на уроке так methodSignatureForSelector:
вернусь nil
- Похоже, вы обнаружили, что и так реализовали свою собственную версию, но это не удается на super
позвонить и так в конечном итоге возвращает подпись forwardInvocation:
- это не то, что вы хотите!
Чтобы обойти это, вам нужно либо направить methodSignatureForSelector:
к классу, у которого есть селектор, или используйте протокол - если класс реализует протокол, он вернет сигнатуру для любых методов в этом протоколе, даже если методы фактически не реализованы этим классом.
Вот ваш пример с использованием протокола:
@protocol DoProtocol
@optional
+ (void) stuff:(int)x;
@end
@interface Do : NSObject<DoProtocol>
@end
@implementation Do
+ (void)forwardInvocation:(NSInvocation *)i
{
const char* argType = [i.methodSignature getArgumentTypeAtIndex:2];
NSLog(@"%s == %s", argType, @encode(id)); // @ == @
NSLog(@"%s == %s", argType, @encode(int)); // @ == i
}
@end
@optional
избегает любых предупреждений компилятора для нереализованных методов. Реализация по умолчанию methodSignatureForSelector:
(от NSObject
) вернет действительную подпись, полученную из протокола, и так forwardInvocation:
будет называться.
Пока вы можете пройти мимо компилятора, все, что вы передадите в качестве аргумента, будет интерпретироваться как таковое во время выполнения - вы можете объявить, что функция принимает NSNumber
, но это вы передаете UITableView
для него это class
все еще будет UITableView
,