2013-02-12 10 views
5

Załóżmy, że mamy inny obiekt, który ma tę samą nazwę metody, ale z różnymi typami argumentów, takimi jak: getMethod:(NSNumber*)aNumber i getMethod:(NSString*)aString.responsesToSelector z różnymi typami argumentów w selektorze

Jak sprawdzić z respondsToSelector lub poprzez inny sposób, jeśli obiekt jest odpowiedzią na selektor z konkretnego typu argumentu coś takiego:

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

Jak można to zrobić? Dzięki.

+3

Nie można zadeklarować dwóch metod o tej samej nazwie i różnych typach parametrów. –

+0

Ok, przypuśćmy, że mamy różne typy obiektów o tej samej nazwie metody, ale z różnymi typami argumentów. Co wtedy robisz? –

+0

będziesz musiał użyć [Objective-C Runtime Functions] (https://developer.apple.com/library/ios/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html#//apple_ref/doc/ uid/TP40001418) bezpośrednio –

Odpowiedz

4

Masz kilka sposobów na znalezienie nazw argumentów dla selektora. Na przykład ten kod zadziała:

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); 
} 

pierwsze i drugie są argumenty dziennika systemu i nie są nimi zainteresowani, więc kolejne linie są drzewa, które trzeba.

również kod poniżej daje sam wynik

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: może mieć wdrożenie takiego na przykład

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

BUT! Ponieważ mamy duże, ale tutaj)) W obu przypadkach będziesz miał nazwy typów argumentów z ciągiem const char * o długości jednego symbolu. Kompilator koduje nazwy typów zgodnie z opisem here. Możesz odróżnić int od char, ale nie UIView od NSString. Dla wszystkich typów identyfikatorów będziesz mieć nazwę typu "@", co oznacza, że ​​jest to id. Smutne ale prawdziwe. Niestety nie znalazłem żadnych sposobów na uzyskanie pełnej nazwy kompletnego typu lub dekodowania. Jeśli znajdziesz tę drogę, daj mi znać.

To jest rozwiązanie. Mam nadzieję, że znajdziesz sposób na wykorzystanie tego podejścia w swoim projekcie.

+0

Dziękuję Rost!Nawet jeśli Twoja odpowiedź nie odpowiada bezpośrednio na moje pytanie, wyjaśnia ona interesujący sposób pracy z Runtime. –

+0

Mam nadzieję, że Apple faceci wydadzą metodę dla moich potrzeb w wersjach funkcji SDK. –

+0

Jest wątpliwe, że będą, ponieważ twoje potrzeby są sprzeczne z ich filozofią pełnego nazewnictwa. Moja sugestia jest po prostu refaktoryzacji, tak aby mieli nazwy, które faktycznie wskazują, co robią. Nawet jeśli jest to tak proste, jak 'getMethodFromNumber:' lub 'getMethodFromString:' – borrrden

0

wont rzeczywiście być w stanie odróżnić typ parametru metody, ale może można zrobić coś takiego zamiast:

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

Nie będzie potrzeby, aby sprawdzić, czy odpowiada selektor ponieważ masz zaznaczone, że jego odpowiedni typ. Może twój problem jest bardziej skomplikowany, ale to powinno zadziałać, jeśli nie.

+0

W rzeczywistości nie jest to pożądany przepływ pracy dla mojej sprawy. –

Powiązane problemy