Primero, no estoy seguro de entender realmente qué es un selector. Según tengo entendido, es el nombre de un método, y puede 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, a pesar de que thing
es claramente un tipo de NSString, y debería responder a minúsculasString, no puedo obtener el condicional 'respondsToSelector' para devolver "SÍ" ...
objective-c
selector
Craig
fuente
fuente
Respuestas:
Debes tener mucho cuidado con los nombres de los métodos. En este caso, el nombre del método es "
lowercaseString
", no "lowercaseString:
" (tenga en cuenta la ausencia de los dos puntos). Es por eso que teNO
devuelven, porque losNSString
objetos responden allowercaseString
mensaje pero no allowercaseString:
mensaje.¿Cómo sabes cuándo agregar dos puntos? Agregue dos puntos al nombre del mensaje si desea agregar dos puntos al llamarlo, lo que sucede si se necesita un argumento. Si toma cero argumentos (como es el caso con
lowercaseString
), entonces no hay dos puntos. Si se necesita más de un argumento, debe agregar los nombres de argumento adicionales junto con sus dos puntos, como encompare:options:range:locale:
.También puede consultar la documentación y observar la presencia o ausencia de dos puntos finales.
fuente
Los selectores son una forma eficiente de hacer referencia a 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).
fuente
Eso es porque quieres
@selector(lowercaseString)
, no@selector(lowercaseString:)
. Hay una sutil diferencia: la segunda implica un parámetro (tenga en cuenta los dos puntos al final), pero- [NSString lowercaseString]
no toma un parámetro.fuente
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
fuente
El método de NSString es
lowercaseString
(0 argumentos), nolowercaseString:
(1 argumento).fuente
No piense en los dos puntos como parte del nombre de la función, piense en él como un separador, si no tiene nada que separar (ningún valor para ir con la función), entonces no lo necesita.
No estoy seguro de por qué, pero todo esto OO parece ser extraño para los desarrolladores de Apple. Sugeriría encarecidamente tomar Visual Studio Express y jugar con eso también. No porque uno sea mejor que el otro, solo es una buena manera de ver los problemas de diseño y las formas de pensar.
Me gusta
Siempre es bueno ver un problema de diferentes maneras y la programación es el enigma definitivo.
fuente
Según tengo entendido de la documentación de Apple, un selector representa el nombre del método al que desea llamar. Lo bueno de los selectores es que puede usarlos en casos en los que varía el método exacto a llamar. Como un simple ejemplo, puede hacer algo como:
fuente
Según los documentos de Apple: https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/Selector.html
Ejemplo: (lldb) punto de interrupción --set selector viewDidLoad
Esto establecerá un punto de interrupción en todas las implementaciones de viewDidLoad en su aplicación. Entonces selector es una especie de identificador global para un método.
fuente