2010-04-20 24 views
10

¿Alguien puede aclararme en cuanto a las diferencias entre las dos declaraciones a continuación.Usando [self method] o @selector (method)?

[self playButtonSound]; 

Y:

[self performSelector:@selector(playButtonSound)]; 

estoy preguntando, ya que tenía algo de código antiguo que utiliza @selector, ahora con un poco más de conocimiento no se me ocurre por qué no hizo uso de [self playButtonSound] en cambio, ambos parecen hacer lo mismo que aquí.

Gary

+0

Gracias, entiendo ahora, muy apreciado. – fuzzygoat

+1

Van: ¿por qué eliminaste esto? Esto es útil, ¿no es así? Definitivamente harán lo mismo. Una pequeña diferencia es que el primer ejemplo será el envío de un mensaje, playButtonSound; el segundo enviará dos mensajes, primero performSelector :, que luego enviará playButtonSound. Siempre iría por la primera opción a menos que no tenga otra opción, aunque solo sea por legibilidad. – fuzzygoat

Respuesta

10

Tanto a lo mismo, pero [self playButtonSound]; es sin duda la forma normal para invocar un método en Objective-C. Sin embargo, usar performSelector: le permite llamar a un método que solo se determina en tiempo de ejecución.

Desde el NSObject Protocol Reference:

El performSelector: método es equivalente a enviar un mensaje de aSelector directamente al receptor. Para ejemplo, los tres de los siguientes mensajes hacen lo mismo:

id myClone = [anObject copy]; 
id myClone = [anObject performSelector:@selector(copy)]; 
id myClone = [anObject performSelector:sel_getUid("copy")]; 

Sin embargo, el método de performSelector: le permite enviar mensajes que no se determinan hasta que el tiempo de ejecución. Un selector de variables se puede pasar como argumento :

SEL myMethod = findTheAppropriateSelectorForTheCurrentSituation(); 
[anObject performSelector:myMethod]; 
+1

Tropezado con esta respuesta y cosas aprendidas! ¡Gracias! – Groot

6
[self playButtonSound]; 

Aquí compilador comprobará si el objeto responde a -playButtonSound mensaje y le dará una advertencia si no lo hace.

[self performSelector:@selector(playButtonSound)]; 

Calling -playButtonSound esta manera usted no conseguirá advertencia del compilador. Sin embargo, puede verificar dinámicamente si los objetos responden a un selector dado, por lo que puede intentar invocar arbitrariamente un selector en un objeto sin especificar su tipo y sin recibir advertencias del compilador (que puede ser útil para llamar métodos opcionales en un delegado de objetos) :

if ([self respondsToSelector:@selector(playButtonSound)]) 
    [self performSelector:@selector(playButtonSound)]; 
+0

Falta un corchete en la línea 'if ([self respondsToSelector: @selector (playButtonSound)]' -it debe ser 'if ([self respondsToSelector: @selector (playButtonSound)])'. –

+2

En realidad, puede tener el compilador lanzar una advertencia a los selectores no declarados agregando -Wdedeclared-selector en el campo de Otros Indicadores de Advertencia en su configuración de construcción. Encuentro que esto es de mucha ayuda. –