Compruebe si existe un método


110

¿Hay alguna forma de que pueda probar si existe un método en Objective-C?

Estoy tratando de agregar un guardia para ver si mi objeto tiene el método antes de llamarlo.


También está la cuestión de si este es el enfoque correcto en primer lugar, ya que las clases Objective-C pueden responder a selectores que no han declarado (vía - forwardInvocation:).
Donal Fellows

Respuestas:


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

72

También está el mensaje estático instanceRespondToSelector: (SEL) selector Lo llamaría así:

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

o así:

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

Esto puede ser útil si desea llamar a un constructor u otro dependiendo de esto (quiero decir, antes de tener la instancia en sí).


1
¿Qué diferencia hay de instanceRespondToSelector de respondsToSelector?
CReaTuS

1
La principal diferencia es que uno es un mensaje de instancia (para probar si existe un mensaje de instancia determinado) mientras que el otro es un mensaje de clase (para probar si existe un mensaje de clase determinado).
Ricard Pérez del Campo

1
+1 para [MyClass instanceRespondToSelector]. Lo necesitaba dentro de un método de creación de inicio: cuando se subclasifica, tal vez sea necesario llamar a un método de superinicialización en lugar de otros (en desuso), ya que self aún no se ha creado y respondsToSelector siempre devolverá NO.
LightMan

12

Utilice respondsToSelector:. De la documentación :

respondeToSelector:

Devuelve un valor booleano que indica si el receptor implementa o hereda un método que puede responder a un mensaje específico.

- (BOOL)respondsToSelector:(SEL)aSelector

Parámetros
aSelector : un selector que identifica un mensaje.

Valor de retorno
YES si el receptor implementa o hereda un método que puede responder a aSelector , en caso contrario NO.


10

Estás buscando respondsToSelector: -

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

Como dice Donal, lo anterior te dice que foo definitivamente puede manejar la recepción del selector de barras. Sin embargo, si foo es un proxy que reenvía la barra a algún objeto subyacente que recibirá el mensaje de barra, entonces respondeToSelector: le dirá NO, aunque el mensaje se reenviará a un objeto que responde a la barra.


1

La verificación de selectores con respondsToSelector es normalmente solo para métodos delegados. No debería utilizar forwardInvocation o proxies para los métodos delegados. Si necesita utilizar respondsToSelector en otras situaciones, es posible que desee asegurarse de que no haya una forma más adecuada de diseñar su programa.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.