2009-04-10 22 views
116

En primer lugar, no estoy seguro de entender realmente qué es un selector. Desde mi punto de vista, es el nombre de un método, y puedes asignarlo a una clase de tipo 'SEL' y luego ejecutar métodos como respondToSelector para ver si el receptor implementa ese método. ¿Alguien puede ofrecer una mejor explicación?Selectores en el objetivo C

En segundo lugar, a este punto, tengo el siguiente código:

NSString *thing = @"Hello, this is Craig"; 

SEL sel = @selector(lowercaseString:); 
NSString *lower = (([thing respondsToSelector:sel]) ? @"YES" : @"NO"); 
NSLog (@"Responds to lowercaseString: %@", lower); 
if ([thing respondsToSelector:sel]) //(lower == @"YES") 
    NSLog(@"lowercaseString is: %@", [thing lowercaseString]); 

Sin embargo, a pesar de que thing es claramente una especie de NSString, y debería responder a lowercaseString, no puedo obtener el 'respondsToSelector' condicional a return "SÍ" ...

+12

Stanford supuesto CS193P 1B asignación? ¡Tengo exactamente la misma pregunta aquí! :) –

+0

Desea leer la descripción del Selector en el sitio del desarrollador de Apple: [Selectores] (https://developer.apple.com/library/mac/#documentation/General/Conceptual/DevPedia-CocoaCore/Selector.html). – lothar

Respuesta

168

Debe tener mucho cuidado con los nombres de los métodos. En este caso, el nombre del método es simplemente "lowercaseString", no "lowercaseString:" (tenga en cuenta la ausencia de dos puntos). Es por eso que obtiene NO devuelto, porque los objetos NSString responden al mensaje lowercaseString, pero no el mensaje lowercaseString:.

¿Cómo sabe cuándo agregar un dos puntos? Agregas dos puntos al nombre del mensaje si agregas dos puntos al llamarlo, lo que sucede si toma un argumento. Si toma cero argumentos (como es el caso con lowercaseString), entonces no hay dos puntos. Si lleva más de un argumento, debe agregar los nombres adicionales de los argumentos junto con sus dos puntos, como en compare:options:range:locale:.

También puede consultar el documentation y observar la presencia o ausencia de un punto posterior.

4

En este caso, el nombre del selector es incorrecto. Los dos puntos aquí son parte de la firma del método; significa que el método toma un argumento. Creo que quiere

SEL sel = @selector(lowercaseString); 
3

El método de NSString es lowercaseString (0 argumentos), no lowercaseString: (1 argumento).

8

Eso es porque quiere @selector(lowercaseString), no @selector(lowercaseString:). Hay una diferencia sutil: la segunda implica un parámetro (tenga en cuenta los dos puntos al final), pero - [NSString lowercaseString] no toma un parámetro.

7

Selectors son una forma eficiente de hacer referencia a los métodos directamente en el código compilado: el compilador es lo que realmente asigna el valor a un SEL.

Otros ya han cubierto la segunda parte de su q, el ':' al final coincide con una firma diferente a la que está buscando (en este caso, esa firma no existe).

1

No piense en los dos puntos como parte del nombre de la función, piénselo como separador, si no tiene nada que separar (no tiene valor para la función), entonces no lo necesita .

No estoy seguro de por qué pero todo esto de OO parece ser extraño para los desarrolladores de Apple. Recomiendo encarecidamente tomar Visual Studio Express y jugar con eso también. No porque uno sea mejor que el otro, simplemente es una buena forma de ver los problemas de diseño y las formas de pensar.

Como

introspection = reflection 
+ before functions/properties = static 
- = instance level 

Siempre es bueno mirar un problema de diferentes maneras y la programación es el rompecabezas final.

0

Según entiendo la documentación de Apple, un selector representa el nombre del método que desea llamar. Lo bueno de los selectores es que puedes usarlos en los casos en que el método exacto que se llama varía. Como un simple ejemplo, se puede hacer algo como:

SEL selec; 
if (a == b) { 
selec = @selector(method1) 
} 
else 
{ 
selec = @selector(method2) 
}; 
[self performSelector:selec];