Controlla se esiste un metodo


111

C'è un modo per verificare se esiste un metodo in Objective-C?

Sto cercando di aggiungere una guardia per vedere se il mio oggetto ha il metodo prima di chiamarlo.


C'è anche la questione se questo sia l'approccio giusto in primo luogo, poiché le classi Objective-C possono rispondere a selettori che non hanno dichiarato (tramite - forwardInvocation:).
Donal Fellows

Risposte:


189
if ([obj respondsToSelector:@selector(methodName:withEtc:)]) {
   [obj methodName:123 withEtc:456];
}

72

C'è anche il messaggio statico InstanceRespondToSelector: (SEL) selector Lo chiameresti così:

[MyClass instancesRespondToSelector:@selector(someMethod:withParams:)]

o così:

[[myObject class] instancesRespondToSelector:@selector(someMethod:withParams:)]

Questo può essere utile se desideri chiamare un costruttore o un altro a seconda di questo (voglio dire, prima di avere l'istanza stessa).


1
Che differenza c'è tra instanceRespondToSelector e respondsToSelector?
CReaTuS

1
La differenza principale è che uno è un messaggio di istanza (per verificare se esiste un messaggio di istanza determinato) mentre l'altro è un messaggio di classe (per verificare se esiste un messaggio di classe determinato).
Ricard Pérez del Campo

1
+1 per [MyClass instancesRespondToSelector]. Ne avevo bisogno all'interno di un metodo di creazione di init: quando la sottoclasse forse è necessario chiamare un metodo super init invece di altri (deprecati), poiché self non è stato ancora creato e respondsToSelector restituirà sempre NO.
LightMan

12

Usa respondsToSelector:. Dalla documentazione :

respondsToSelector:

Restituisce un valore booleano che indica se il destinatario implementa o eredita un metodo che può rispondere a un messaggio specificato.

- (BOOL)respondsToSelector:(SEL)aSelector

Parametri
aSelector - Un selettore che identifica un messaggio.

Valore restituito
YES se il destinatario implementa o eredita un metodo che può rispondere a aSelector , altrimenti NO.


10

Stai cercando replysToSelector: -

if ([foo respondsToSelector: @selector(bar)] {
  [foo bar];
}

Come dice Donal, quanto sopra ti dice che foo può sicuramente gestire la ricezione del selettore della barra. Tuttavia, se foo è un proxy che inoltra bar a qualche oggetto sottostante che riceverà il messaggio bar, allora replysToSelector: ti dirà NO, anche se il messaggio verrà inoltrato a un oggetto che risponde a bar.


1

Il controllo dei selettori con respondsToSelector è normalmente solo per i metodi delegati. Non dovresti usare forwardInvocation o proxy per i metodi delegati. Se hai bisogno di usare replysToSelector in altre situazioni potresti voler assicurarti che non ci sia un modo più appropriato per progettare il tuo programma.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.