ld: дублированный символ - вызван const - PullRequest
16 голосов
/ 06 марта 2012

Я определял NSString для использования в качестве домена ошибки в NSError и копировал, как там работает ASIHttpRequest.

NSString* const FPServerAPIErrorDomain = @"FPServerAPIErrorDomain";

Я поместил const в его собственный .h файл // FPServerAPICoordinatorConstants.h

#ifndef FirePlayer_FPServerAPICoordinatorConstants_h
#define FirePlayer_FPServerAPICoordinatorConstants_h

NSString* const FPServerAPIErrorDomain = @"FPServerAPIErrorDomain";

#endif

но когда я включил его в несколько .m

SomeFile.m

#import "FPServerAPICoordinatorConstants.h"

SomeOtherFile.m

#import "FPServerAPICoordinatorConstants.h"

Я получил ошибку компоновщика 'дублированный символ'

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

поэтому я изменил const на #define, и он работал нормально.

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

Но есть ли способ получить const в глобальном пространстве, чтобы не выбрасывать «дубликат символа»?

Ответы [ 3 ]

51 голосов
/ 06 марта 2012

В вашем заголовочном файле вы хотите:

extern NSString *const FPServerAPIErrorDomain;

, а затем в файле реализации (так что, вероятно, вы хотите FPServerAPICoordinatorConstants.m), вы захотите:

NSString *const FPServerAPIErrorDomain = @"FPServerAPIErrorDomain";

Затем вы можете импортировать заголовок в несколько файлов и не получать повторяющиеся ошибки символов.

[Кстати, вам не нужны #ifndef охранники, если вы используете #import.]

3 голосов
/ 06 марта 2012

Невозможно создать одну и ту же (глобальную) переменную дважды в одном и том же пространстве имен (без сообщения об ошибке).

1 голос
/ 06 марта 2012

Каждый символ должен быть определен только один раз;то есть он должен быть определен только в одном файле m.Поместив определение в заголовочный файл, оно будет определено в каждом m-файле, который включает этот заголовок.

Определите его в одном из ваших m-файлов (в зависимости от того, что наиболее актуально) и измените то, что есть в заголовке.в объявление (используя ключевое слово extern).

Определение освобождает место для данных;объявление просто сообщает компилятору, что где-то есть определение.Поэтому каждый m-файл, который использует константу, должен иметь объявление, но только один m-файл должен иметь определение.

...