objective-c cocoa cocoa-touch c-preprocessor stringification

objective c - Valor de macro del preprocesador para literal de cadena Objective-C



cocoa cocoa-touch (4)

Tengo una macro de preprocesador definida en la configuración de compilación

FOO=BAR

Ese valor que quiero aplicar en un literal de cadena de Objective-C que se puede pasar a un método. La siguiente #define no funciona, pero debería demostrar lo que estoy tratando de lograr:

#define FOOLITERAL @"FOO" //want FOOLITERAL to have the value of @"BAR" myMethodThatTakesAnNSString(FOOLITERAL);

Espero que me esté perdiendo lo obvio de alguna manera, pero parece que no puedo encontrar el vudú del preprocesador adecuado para obtener lo que necesito.


¿Qué error estás viendo exactamente? Este tipo de cosas funciona como usted espera:

#define kMyString @"MyString" [NSString stringWithFormat:@"macro: %@", kMyString];


Aquí hay una versión modificada de la respuesta de Adam Rosenfield con una semántica más clara:

#define NSStringize_helper(x) #x #define NSStringize(x) @NSStringize_helper(x)

Lo uso para reemplazar código como este:

case OneEnumValue: name = @"OneEnumValue"; break; case AnotherEnumValue: name = @"AnotherEnumValue"; break;

con este:

#define case_for_type(type) case type: name = NSStringize(type); break case_for_type(OneEnumValue); case_for_type(AnotherEnumValue);


Es necesario definir la macro preprocesador como,

FOO=/@/"BAR/"

Y usa el lado del código como,

[NSString stringWithFormat:@"macro: %@", FOO];


Use el operador de creación de cadenas # para hacer una cadena C fuera del símbolo. Sin embargo, debido a una peculiaridad del preprocesador, necesita usar dos capas adicionales de macros:

#define FOO BAR #define STRINGIZE(x) #x #define STRINGIZE2(x) STRINGIZE(x) #define FOOLITERAL @ STRINGIZE2(FOO) // FOOLITERAL now expands to @"BAR"

El motivo de las capas adicionales es que el operador de creación de cadenas solo se puede utilizar en los argumentos de la macro, no en otros tokens. En segundo lugar, si un argumento de una macro tiene el operador de alineación aplicado en el cuerpo de la macro, ese argumento no se expandirá como otra macro. Entonces, para asegurarnos de que FOO se expande, STRINGIZE2 otra macro, de modo que cuando STRINGIZE2 se expande, también expande FOO porque el operador de encordado no aparece en el cuerpo de esa macro.