2012-03-06 13 views
15

Stavo definendo un NSString da utilizzare come dominio di errore in NSError e stavo copiando come ASIHttpRequest stava facendo.ld: simbolo duplicato - causato da const

NSString* const FPServerAPIErrorDomain = @"FPServerAPIErrorDomain"; 

ho messo il const nel proprio file h // FPServerAPICoordinatorConstants.h

#ifndef FirePlayer_FPServerAPICoordinatorConstants_h 
#define FirePlayer_FPServerAPICoordinatorConstants_h 

NSString* const FPServerAPIErrorDomain = @"FPServerAPIErrorDomain"; 

#endif 

ma quando ho incluso in più di una .m

SomeFile.m 

#import "FPServerAPICoordinatorConstants.h" 

SomeOtherFile.m 

#import "FPServerAPICoordinatorConstants.h" 

ho avuto errore linker "duplicate symbol"

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

quindi cambio il const in #define e ha funzionato bene.

// 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 

Ma c'è un modo per ottenere il const nello spazio globale per non gettare il "simbolo duplicato"?

+2

se si lascia fuori il includono magia di file, è la tua domanda lo stesso: "Posso fare const ** int i = 42; ** due volte nella stessa fonte/binario –

+0

sì, ma anche 'come non si? usa #defines e usa const nello spazio globale '? è possibile? è preferibile? #define funziona, ma perché hanno allora i comandi? Im una persona java spostata in obj-c ho qualificato in voodoo 101 ancora –

+0

non hai copiato ciò ASIHttpRequest sta facendo affatto tornare indietro e guardare di nuovo – hooleyhoop

risposta

47

Nel file di intestazione che si desidera:

extern NSString *const FPServerAPIErrorDomain; 

e poi in un file di implementazione (quindi probabilmente si desidera un FPServerAPICoordinatorConstants.m) si vuole:

NSString *const FPServerAPIErrorDomain = @"FPServerAPIErrorDomain"; 

Quindi è possibile importare l'intestazione in più file e non ottenere errori di simboli duplicati.

[A proposito, non è necessario il #ifndef guardie se si sta utilizzando #import.]

+0

ha ap! ple mettere ifndef in :) quando ho aggiunto il file di intestazione dai modelli –

+0

Questo probabilmente è dovuto al fatto che è stato aggiunto da un modello "C header".Questo li avrà in modo predefinito, come li vorrai se userai '# include' s in stile C. Ma stai usando '# import's in stile Objective-C. Quindi sbarazzati delle guardie. – mattjgalloway

+0

Grazie mille per la tua risposta. Risparmia tempo per me. – Yanhua

3

Non è possibile creare un'istanza della stessa variabile (globale) due volte nello stesso spazio dei nomi (, senza ottenere un errore).

+1

c'è qualche vantaggio di utilizzare // NSString * const FPServerAPIErrorDomain = @ "FPServerAPIErrorDomain";.. oltre #define FPServerAPIErrorDomain @ "FPServerAPIErrorDomain" –

1

Ogni simbolo deve essere definita solo una volta; cioè, dovrebbe essere definito solo in un file m. Inserendo la definizione in un file di intestazione, viene definita in ogni file m che include quell'intestazione.

Definirlo in uno dei tuoi file m (a seconda di quale sia il più pertinente) e modificare ciò che si ha nell'intestazione in una dichiarazione (utilizzando la parola chiave extern).

La definizione rende lo spazio per i dati; la dichiarazione dice semplicemente al compilatore che esiste una definizione da qualche altra parte. Quindi ogni file m che utilizza la costante deve avere una dichiarazione, ma solo un file m dovrebbe avere la definizione.

+0

c'è qualche vantaggio nell'usare // NSString * const FPServerAPIErrorDomain = @ "FPServerAPIErrorDomain"; su #define FPServerAPIErrorDomain @ "FPServerAPIErrorDomain" –