2010-02-15 8 views
11

En Objective-C, que puede escribir:Entender la línea entre Objective-C y la Fundación, NSString específicamente

id pString = @"Hello, World."; 

y el compilador será una instancia de un NSString sin que yo tenga que llamar explícitamente un método de fábrica. Sin embargo, NSString es realmente solo una clase Foundation y, por lo tanto, presumiblemente no forma parte de la definición real del lenguaje Objective-C.

Entonces, cuando escribo @"String", ¿cómo sabe el compilador construir un NSString en particular, y no algún otro objeto tipo cadena? En otras palabras, ¿dónde se detiene el lenguaje Objective-C y se inicia la biblioteca Foundation ?

+0

'@" "' es parte de la definición 'objective-c', crea un objeto' NSString' ... en oposición a la cadena simple 'char *' definida en 'c' con' "" ' – stefanB

Respuesta

6

Cuando escribe código Objective-C fuera de los entornos Cocoa o GNUStep, @"..." no está vinculado a NSString.

En este caso, GCC proporciona una opción para especificar una clase asociada a las cadenas literales:

-clase cadena -fconstant = nombre-clase
Uso clase nombre que el nombre de la clase a instancia para cada cadena literal especificada con la sintaxis "@" ... "". El nombre de clase predeterminado es "NXConstantString".

+2

Este enlace proporciona un poco más de información: http://gcc.gnu.org/onlinedocs/gcc/Constant-string-objects.html –

+0

¡Gracias por publicar! No tenía idea de cómo funcionaba. – kubi

+0

¿hay alguna manera de usar ese indicador de compilador implícitamente, así que no tendré que seguir escribiéndolo cada vez que quiera compilar? –

3

La directiva @"" parece estar incorporada en el compilador objetivo-c.

Por ejemplo, si se quita todos los #import s de su archivo de origen .m (& cabecera prefijo), la siguiente línea será un error de sintaxis:

NSString *string = @"ABCD"; // (Doesn't know anything about NSString class)

Sin embargo, si cambia la Fundación NSString tipo a la incorporada en el void tipo, se compilará bien:

void *string = @"ABCD";

lo tanto, incluso sin la definición NSString de Foundation, el compilador sabe cómo convertir @"" en algo que puede convertirse en una instancia NSString en tiempo de ejecución (probablemente no creará una instancia sin Foundation, pero al compilador no parece importarle); Como acepta la sintaxis sin necesidad de ninguna definición de biblioteca externa, el compilador ve @"" como parte del lenguaje.

Su código, sin embargo, no podrá hacer uso de ninguna instancia @"" sin importar Foundation.h, por lo que desde el punto de vista de su programa, @"" es parte de la biblioteca.

0

Otro dato interesante es que una cadena de Objective-C literal (@"" notación) devuelve el mismo tipo como una instancia explícita NSString objeto:

#import <Foundation/Foundation.h> 
#import <objc/runtime.h> 

int main (int argc, const char * argv[]) { 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 

    printf("string literal class: %s\n", object_getClassName(@"a string literal");); 

    NSString *str = [[NSString alloc] initWithUTF8String:"asdf"]; 
    printf("explicit NSString class: %s", object_getClassName(str)); 

    [pool drain]; 
    return 0; 
} 

vagamente recuerdo que en otras implementaciones, más antiguas de Objective-C , el literal de cadena en realidad devolvió un objeto de una clase ligeramente diferente, pero que podría usarse indistintamente con NSString/NSCFString. Sin embargo, no estoy totalmente seguro de esa parte.

Cuestiones relacionadas