#import все еще получает ошибку "дубликат символа" - PullRequest
10 голосов
/ 02 мая 2010

Когда я компилирую приложение для iPhone, xCode выдает ошибку «duplicate symbol» для моих переменных в MyConstants.h

Я подумал, если бы я использовал:

#import "MyConstants.h"

этого бы избежать?

Но у меня все еще есть проблема.

Добавлена ​​информация:

Ошибка возникает при «связывании». (Я просто использую кнопку xCode «Build and Go».)

Я также попробовал (не нужно с #import) метод # ifndef / def.

Может быть, я должен просто спросить это:

Если вам нужен доступ к константе в КАЖДОМ части ALL ваших файлов исходного кода ... что бы вы поместили в ваш .h файл? Что бы вы использовали, чтобы включить эту константу в другие части вашего кода.

Я подумал (но, наверное, это не так), это было просто:

MyConstants.h> int thisIsGlobal = 123;

(Нет, где я переопределяю этот глобальный глобус в любом коде.)

А затем просто "#import MyConstants.h" вверху каждого из моих других исходных файлов.

Ответы [ 5 ]

20 голосов
/ 03 мая 2010

Что вы можете сделать, это поместить в заголовок (MyConstants.h):

extern const int MyConstant;
extern NSString * const MyStringConstant;

И в исходном файле включите заголовок выше, но определите константы (MyConstants.m):

const int MyConstant = 123;
NSString * const MyStringConstant = @"SomeString";

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

Проблема с объявлением и определением константы в заголовке (которая не объявлена ​​как static) заключается в том, что компилятор обрабатывает ее как независимый глобал для каждого файла, который включает этот заголовок. Когда компоновщик пытается связать все ваши скомпилированные исходники вместе, он встречает глобальное имя столько раз, сколько вы включили MyConstants.h.

8 голосов
/ 03 мая 2010

Два варианта:

static const int thisIsGlobal = 123;

или

#define thisIsGlobal 123
5 голосов
/ 19 июля 2011

Я использую вот так, и работает: (в .h за пределами @interface)

static NSString * const mkLocaleIdentifierUS = @"en_US";
static NSString * const mkLocaleUserSystemSettings = nil;
3 голосов
/ 04 мая 2010

Это связано с тем, что рассматриваемое имя символа (thisIsGlobal) отправляется в каждый созданный объектный файл, где заголовок, содержащий объявление для thisIsGlobal, включен и видим.

Примеры, предоставленные другим постером: 'extern const int MyConstant;' это лучший способ, если вам не нужно, чтобы значение было видимым, в этом случае вы можете использовать перечисление:

int thisIsGlobal = 123; // плохо

enum {thisIsGlobal = 123}; // ок

при использовании статического элемента в большой программе будет появляться много скрытых символов - не используйте его. Использование определения также пугает (учитывая, что есть более безопасные альтернативы, почему бы не использовать их?).

2 голосов
/ 04 мая 2010

Я обычно помещаю файл моих констант приложения в файл MyApplication_Prefix.pch проекта Xcode, обычно расположенный в группе Other Sources. Любой заголовочный файл, включенный в этот pch файл, будет включен из всех файлов вашего проекта.

После добавления этого оператора включения вам больше не нужно будет включать файл MyConstants.h из каждого файла в вашем проекте - он будет включен автоматически.

...