2012-03-06 19 views
15

Estaba definiendo un NSString para usar como dominio de error en NSError y estaba copiando cómo estaba haciendo ASIHttpRequest.ld: símbolo duplicado - causado por const

NSString* const FPServerAPIErrorDomain = @"FPServerAPIErrorDomain"; 

pongo la const en su propio archivo .h // FPServerAPICoordinatorConstants.h

#ifndef FirePlayer_FPServerAPICoordinatorConstants_h 
#define FirePlayer_FPServerAPICoordinatorConstants_h 

NSString* const FPServerAPIErrorDomain = @"FPServerAPIErrorDomain"; 

#endif 

pero cuando lo incluí en más de un .m

SomeFile.m 

#import "FPServerAPICoordinatorConstants.h" 

SomeOtherFile.m 

#import "FPServerAPICoordinatorConstants.h" 

que tiene error de enlazador 'símbolo duplicado'

ld: duplicate symbol _FPServerAPIErrorDomain in SomeFile.o and ....SomeOtherFile.o for architecture armv7 

así que cambio el const a #define y funcionó bien.

// FPServerAPICoordinatorConstants.h 

#ifndef FirePlayer_FPServerAPICoordinatorConstants_h 
#define FirePlayer_FPServerAPICoordinatorConstants_h 


//THIS WAS TRIGGERING link errors 
//NSString* const FPServerAPIErrorDomain = @"FPServerAPIErrorDomain"; 
//working OK 
#define FPServerAPIErrorDomain @"FPServerAPIErrorDomain" 

#endif 

¿Pero hay una manera de obtener la const en el espacio global para no arrojar 'símbolo duplicado'?

+2

si omite el archivo de inclusión mágico, ¿su pregunta es la misma que: "puedo hacer ** const int i = 42; ** dos veces en la misma fuente/binario? –

+0

sí, pero también '¿cómo NO use #defines y use const en el espacio global '? ¿es posible? ¿es preferible? #define funciona, pero ¿por qué entonces tiene consts? Soy una persona java movida a Obj-c No he calificado en el vudú 101 aún –

+0

No ha copiado ASIHttpRequest lo está haciendo en absoluto volver atrás y mirar de nuevo – hooleyhoop

Respuesta

47

En el archivo de cabecera que desee:

extern NSString *const FPServerAPIErrorDomain; 

y luego en un archivo de aplicación (lo que probablemente desea un FPServerAPICoordinatorConstants.m) que le conviene:

NSString *const FPServerAPIErrorDomain = @"FPServerAPIErrorDomain"; 

A continuación, puede importar el encabezado en archivo múltiple y no obtener errores de símbolos duplicados.

[Por cierto, no es necesario #ifndef los guardias si está usando #import.]

+0

ha ap! Por ejemplo, puse el ifndef en :) cuando agregué el archivo de encabezado de las plantillas –

+0

Probablemente sea porque lo ha agregado de una plantilla de "encabezado C".Eso los tendrá por defecto, ya que los necesitarás si usas el estilo C '# include's. Pero estás usando Objective-C-style '# import's. Así que deshazte de los guardias. – mattjgalloway

+0

Muchas gracias por su respuesta. Ahorra tiempo para mi – Yanhua

3

No se puede instanciar la misma variable (global) dos veces en el mismo espacio de nombres (, sin obtener un error).

+1

¿hay alguna ventaja de utilizar // NSString * const FPServerAPIErrorDomain = @ "FPServerAPIErrorDomain";.. sobre #define FPServerAPIErrorDomain @ "FPServerAPIErrorDomain" –

1

Cada símbolo sólo debe definirse una vez; es decir, solo se debe definir en un archivo m. Al poner la definición en un archivo de cabecera, se define en cada archivo m que incluye ese encabezado.

Defínalo en uno de sus m archivos (lo que sea más relevante), y cambie lo que tiene en el encabezado a una declaración (usando la palabra clave extern).

La definición deja espacio para los datos; la declaración simplemente le dice al compilador que hay una definición en otro lugar. Entonces cada archivo m que usa la constante necesita tener una declaración, pero solo un archivo m debe tener la definición.

+0

hay alguna ventaja de usar // NSString * const FPServerAPIErrorDomain = @ "FPServerAPIErrorDomain"; sobre #define FPServerAPIErrorDomain @ "FPServerAPIErrorDomain" –

Cuestiones relacionadas