objective c - Selectores en el objetivo C
objective-c (7)
Debes 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 no recibirá NSString
, porque los objetos NSString
responden al mensaje NSString
pero no al mensaje NSString
lowercaseString:
¿Cómo sabes 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 de 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 las compare:options:range:locale:
También puede consultar la documentation y observar la presencia o ausencia de un punto final.
Primero, 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?
En segundo lugar, hasta 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, aunque es claramente un tipo de NSString, y debería responder a lowercaseString, no puedo obtener el condicional ''responddsToSelector'' para devolver "SÍ" ...
Desde mi comprensión de 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, puedes hacer algo como:
SEL selec;
if (a == b) {
selec = @selector(method1)
}
else
{
selec = @selector(method2)
};
[self performSelector:selec];
El método de NSString es lowercaseString (0 argumentos), no lowercaseString:
(1 argumento).
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 quieres
SEL sel = @selector(lowercaseString);
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.
No pienses en los dos puntos como parte del nombre de la función, piénsalo como un separador, si no tienes nada que separar (sin valor para la función) entonces no lo necesitas.
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.
Me gusta
introspection = reflection
+ before functions/properties = static
- = instance level
Siempre es bueno ver un problema de diferentes maneras y la programación es el enigma definitivo.
Selectors son una forma eficiente de referenciar métodos directamente en 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).