2010-08-14 12 views
11

Hay algunas funciones que toman como argumento @selector (methodName). Usé NSLog para descubrir qué es @selector y devuelve un número entero. Parece un PID, pero cuando ejecuté ps ax no pude encontrar el PID. ¿Qué representa ese entero y por qué tenemos que usar @selector todo el tiempo en lugar de simplemente pasar el nombre del método?¿Qué es realmente un @selector?

+7

Los literales '@ selector' no se evalúan como enteros. Imprimir cualquier cosa como un entero nunca fallará, aunque si intenta un tamaño incorrecto de entero, puede imprimir el resultado incorrecto (parte del valor real cortado). Lo que es más importante, imprimir cosas que no son enteros como enteros "funcionará" (imprimirá un número) pero no logrará nada (el número será inútil para usted). Como Dave DeLong le dijo, un literal '@ selector 'se evalúa como' SEL', que (en la implementación actual) es en realidad un puntero. –

+0

Ningún selector es un número entero. Ves esto cuando desarmas el código. Pero desde el punto de vista Objective-C no es un número entero. Bueno, tal vez decir que es un valor escalar podría ser más preciso. – Lothar

Respuesta

35

@selector() es una directiva de compilación para convertir lo que está dentro del paréntesis en SEL. Un SEL es un tipo para indicar un nombre de método, pero no la implementación del método. (Para eso necesitaría un tipo diferente, probablemente un IMP o un Method) Bajo la capucha, un SEL se implementa como un char*, aunque confiar en ese comportamiento no es una buena idea. Si desea inspeccionar lo SEL que tiene, la mejor manera de hacerlo es a convertirlo en un NSString* así:

NSLog(@"the current method is: %@", NSStringFromSelector(_cmd)); 

(suponiendo que conoce que _cmd es uno de los parámetros ocultos de cada llamada a un método, y es el SEL que corresponde al método actual)

El Objective-C Programming Language Guide tiene mucha más información sobre el tema.

+1

+1 para detallar. – harshalb

+9

'SEL' ya no es una cadena C; apunta a un tipo opaco definido en libobjc. El primer miembro es una cadena C para fines de compatibilidad, pero se supone que no debes confiar en eso; el código apropiado usa 'sel_getName' para acceder realmente al miembro de C-string, o' NSStringFromSelector' para crear un NSString a partir de él. –

+0

@Peter gracias por la aclaración. –

-2

creo que mirando la puesta en práctica de Objective-C podría ser bueno para la comprensión:

Un selector es un valor entero. Pero su tipo es diferente de los valores enteros normales de C, por lo que no puede asignarlos.

El nombre de selector como "nombreMetodo" es la cadena que representa un nombre exclusivo para este entero.

Otros idiomas y sistemas llaman a este programa único cadena ancha a un mapeo entero de un átomo (Windows) o quark (GTK).

Objective-C mantiene todas las funciones para una clase dentro de una tabla hash. La clave hashtable es un número entero. La biblioteca de tiempo de ejecución Objective-C busca la tabla hash en cada invocación de método. Sin el número entero único, sería mucho más lento realizar esta búsqueda crítica.

Un selector ya no es un puntero opaco para una estructura. Con MacOSX 10.6, la función de tiempo de ejecución obj_send que implementa la invocación del método Objective-C está utilizando una operación aritmética en el selector al principio para averiguar si se trata de un retener, liberar, liberar el mensaje y hacer algo en estos casos especiales. Por ejemplo, simplemente regrese en caso de que esté utilizando el recolector de basura.

+0

Um, la "operación entera" en cuestión es simplemente una comparación con un valor conocido, que es el mismo para enteros y punteros. En el nivel de ensamblaje, son lo mismo. En realidad, los SEL siguen siendo punteros de cadena C internamente en todos los tiempos de ejecución de Apple. (Son una estructura en los tiempos de ejecución de gcc y GNUstep). Sin embargo, se declaran como 'typedef struct objc_selector * SEL' para crear un tipo opaco, y la implementación puede cambiar el significado en cualquier momento. –

+0

En este caso, un selector debe apuntar a una ubicación de memoria válida. ¿Ellos? Y lo que hace GNUstep no es relevante, así que está fuera de la liga. – Lothar

+0

Ya no puedo encontrar el artículo, pero si son simples punteros, ¿cómo puede una sola comparación ser una rama de ruta rápida para 3 selectores diferentes? Debe haber más detrás de esto en MacOSX 10.6 – Lothar

Cuestiones relacionadas