2009-07-09 1 views
7

Sto iterando attraverso un NSArray che contiene molti tipi diversi di oggetti. Ci sono molti metodi per capire quale classe è l'oggetto. Tuttavia, non sono stato in grado di trovare un buon modo per scoprire se un oggetto può implementare una particolare funzione. Posso metterlo in un try-catch ma emetterà comunque un messaggio di errore nella console anche se sto rilevando l'errore. C'è un modo migliore per farlo?Come posso sapere se un oggetto implementa un metodo particolare?

semplice esempio:

@try { 
    if ([element lowercaseString]) { 
     //do something 
    } 
} 
@catch (id theException) { 
    // do something else 
} 
+1

Verificare la presenza di respondsToSelector come molti hanno risposta. In Objective-C non è un buon stile (secondo me e molti altri) usare le eccezioni per controllare il flusso del programma tranne che per errori nella programmazione. Come stai verificando se esiste un metodo in questo caso, non è appropriato. – Abizern

risposta

22

Come suggerito, è possibile utilizzare respondsToSelector: messaggio dichiarato NSObject. Il codice fornito sarebbe come

if ([element respondsToSelector:@selector(lowercaseString)]) { 
    // ... do work 
} 
+1

+1 per la risposta migliore con esempio di collegamento e codice. –

+8

Non dimenticare che i due punti sono una parte inseparabile del selettore. @selector (catFish) è completamente diverso da @selector (catFish :). – Chuck

+0

hey c'è un modo per fare qualcosa di simile per le proprietà? se ho un oggetto id generico che ho estratto da un array, voglio sapere se ha una certa proprietà ... – topwik

5

sguardo al metodo respondsToSelector di NSObject

1

una categoria generica bello avere nel codice è questo:

@interface NSObject (KMExtensions) 

- (id)performSelectorIfResponds:(SEL)aSelector; 
- (id)performSelectorIfResponds:(SEL)aSelector withObject:(id)anObject; 

@end 

@implementation NSObject (KMExtensions) 

- (id)performSelectorIfResponds:(SEL)aSelector 
{ 
    if ([self respondsToSelector:aSelector]) { 
     return [self performSelector:aSelector]; 
    } 
    return NULL; 
} 

- (id)performSelectorIfResponds:(SEL)aSelector withObject:(id)anObject 
{ 
    if ([self respondsToSelector:aSelector]) { 
     return [self performSelector:aSelector withObject:anObject]; 
    } 
    return NULL; 
} 

@end 

e quindi è possibile utilizzare:

[element performSelectorIfResponds:@selector(lowercaseString)];