Ld: дублирующий символ - вызванный константой
Я определял 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 в глобальном пространстве не "дублировать символ"?
Ответы
Ответ 1
В вашем файле заголовка вы хотите:
extern NSString *const FPServerAPIErrorDomain;
а затем в файле реализации (возможно, вам понадобится FPServerAPICoordinatorConstants.m
):
NSString *const FPServerAPIErrorDomain = @"FPServerAPIErrorDomain";
Затем вы можете импортировать заголовок в несколько файлов и не получать повторяющиеся ошибки символов.
[Кстати, вам не нужны защитники #ifndef
, если вы используете #import
.]
Ответ 2
Невозможно создать одну и ту же (глобальную) переменную дважды в том же пространстве имен (без получения ошибки).
Ответ 3
Каждый символ должен быть определен только один раз; то есть он должен быть определен только в одном файле m. Поместив определение в файл заголовка, он определяется в каждом файле m, который включает этот заголовок.
Определите его в одном из ваших файлов m (в зависимости от того, что наиболее важно) и измените то, что у вас есть в заголовке, на объявление (используя ключевое слово extern).
Определение содержит пространство для данных; объявление просто сообщает компилятору, что есть определение где-то еще. Поэтому каждый m файл, который использует константу, должен иметь объявление, но только один файл m должен иметь определение.