2013-02-12 3 views
5

Предположим, у нас есть другой объект, который имеет то же имя метода, но с различными типами аргументов типа: getMethod:(NSNumber*)aNumber и getMethod:(NSString*)aString.responsesToSelector с разными типами аргументов в селекторе

Как проверить с respondsToSelector или через другой путь, если объект реагирует на селектор с определенным типом аргумента, что-то вроде этого:

[myObjectA respondsToSelector:@selector(getMethod:(NSNumber*))] 

Как вы это сделать? Спасибо.

+3

Вы не можете объявить два метода с тем же именем и разными типами параметров. –

+0

Хорошо, предположим, что у нас есть разные типы объектов с тем же именем метода, но с разными типами аргументов. Что вы тогда делаете? –

+0

вам нужно будет использовать функции [Objective-C Runtime Functions] (https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html#//apple_ref/doc/ uid/TP40001418) напрямую –

ответ

4

У вас есть несколько способов найти имена типов аргументов для селектора. Например, этот код будет работать:

Method method = class_getInstanceMethod([self class], @selector(someMethod:param2:param3:)); 
char type[256]; 
int argsNumber = method_getNumberOfArguments(method); 
for (int i = 0; i < argsNumber; i++) { 
    method_getArgumentType(method, i, type, 256); 
    NSLog(@"%s", type); 
} 

Первые и вторые аргументы журнала являются системами, и вы не заинтересованы в них, так еще дереве линии является то, что вам нужно.

также ниже код даст вам тот же результат

NSMethodSignature *sig = [self methodSignatureForSelector:@selector(someMethod:param2:param3:)]; 
int args = [sig numberOfArguments]; 
for (int i = 0; i < args; i++) { 
    NSLog(@"%s", [sig getArgumentTypeAtIndex:i]); 
} 

someMethod:param2:param3: может иметь реализацию, как это, например

- (BOOL) someMethod:(NSString *)str param2:(UIView *)view param3:(NSInteger)number 
{ 
    return NO; 
} 

НО! Причина у нас большая, но здесь)) В обоих случаях у вас будут аргументы, имена типов с строкой const char * с длиной одного символа. Компилятор кодирует имена типов, как описано here. Вы можете отличать int от char, но не UIView от NSString. Для всех типов идентификаторов вы будете иметь имя типа '@', что означает, что это id. Печально, но верно. К сожалению, я не нашел способов получить полное полное имя типа или декодирование. Если вы найдете этот способ, дайте мне знать PLS.

Так что это решение. Надеюсь, вы найдете способ использования этого подхода в своем проекте.

+0

Спасибо, Рост!Даже если ваш ответ напрямую не отвечает на мой вопрос, он объясняет интересный способ работы с Runtime. –

+0

Надеюсь, что ребята из Apple выпустят метод для моих нужд в выпуске функций SDK. –

+0

Сомнительно, что они будут, потому что ваши потребности идут вразрез с их философией подробного наименования. Мое предложение состоит в том, чтобы просто реорганизовать так, чтобы у них были имена, которые фактически указывают, что они делают. Даже если это так просто, как 'getMethodFromNumber:' или 'getMethodFromString:' – borrrden

0

Вы обыкновение фактически быть в состоянии отличить тип параметра метода, но, может быть, вы могли бы сделать что-то вроде этого, вместо:

if([myObject isKindOfClass:[A class]]) 
    [myObjectA getMethod:aNumber]; 
else if([myObject isKindOfClass:[B class]]) 
    [myObjectA getMethod:aString]; 

вам не нужно, чтобы проверить, если он реагирует на селектор, так как вы проверили, что сво правильный тип. Возможно, ваша проблема сложнее, но это должно сработать, если это не так.

+0

На самом деле это не желаемый рабочий процесс для моего случая. –

Смежные вопросы