Как мне динамически установить статическую переменную «#define» в файле заголовка (.h)?

#objective-c #ios4 #sharekit

#objective-c #ios4 #sharekit

Вопрос:

Я использую компонент с открытым исходным кодом в моем проекте iOS (sharekit), и они определили статические переменные в файле заголовка. Например, в SHKConfig.h они определяют название приложения как:

 #define SHKMyAppName            @"My App Name"
  

Что я хотел бы сделать, так это сделать это динамическим; Я не хочу жестко кодировать эти переменные в этом конкретном файле. Поскольку в файле заголовка, очевидно, нет viewDidLoad метода (насколько я знаю), как я мог бы динамически назначить эту переменную?

Возможно ли это вообще?

Заранее большое вам спасибо!!!

Комментарии:

1. Как вы компилируете свой исходный код? Вероятно, вы могли бы добавить -D SHKMyAppName="Whatever You Want" в параметры компилятора. Честно говоря, не уверен, работает ли это в LVVM, но работает в GCC.

Ответ №1:

#define всегда вычисляется во время компиляции кода. Вам следует модифицировать библиотеку, чтобы получить эту функциональность.

Другое решение заключается в следующем. Создайте некоторый класс Provider с

   (NSString *)getYourConstant;
  

метод и используйте следующий макрос

 #import "Provider.h"

#define kTheConstantYouNeed [Provider getYourConstant]
  

Комментарии:

1. будет ли это оценено во время выполнения? Или этот метод будет вызываться только во время компиляции? (ваш пример кода)

2. Во время компиляции кода все вхождения SHKMyAppName будут заменены (в виде строки) правой частью. Таким образом, во время выполнения вместо @»My App Name» вы получите фактический вызов метода.

3. идеально! Спасибо!! и последний вопрос: в файлы, куда внедряется этот метод, должен ли я импортировать класс utilities (Provider.h в вашем примере) или, поскольку он импортирован в файл заголовка макроса, мне не нужно?

4. Нет, вы не должны. Если файл имеет доступ к этой константе, он также будет иметь весь импорт из файла, в котором она определена.

Ответ №2:

Вы могли бы использовать ifdef препроцессор макросов для переопределения переменной во время компиляции. Вы никак не можете «изменить эту переменную», поскольку это даже не переменная для начала. Это МАКРОС, который заменяет все вхождения SHKMyAppName на @"My App Name .

Вот что вы могли бы сделать. Определите переменную компилятора (вы можете сделать это в конфигурациях проекта XCode) с именем проекта, который вы создаете. Затем замените #define на:

 #if defined(PROJECT_APP_01_BUILD)
#define SHKMyAppName @"My App 01"
#elif defined(PROJECT_APP_02_BUILD)
#define SHKMyAppName @"My App 02"
#elif defined(PROJECT_APP_03_BUILD)
#define SHKMyAppName @"My App 03"
#endif
  

Таким образом, при компиляции приложения 01 макрос SHKMyAppName будет заменен на @"My App 01"'. When you are compiling **App 02**, macro SHKMyAppName will be replaced by @»Мое приложение 02″‘. И так далее, и тому подобное.

Ответ №3:

Вы могли бы переместить эти определения в один файл appinfo.h и включить его в другие заголовки.

Это также может быть хорошим местом для информации о версии.

Например.

В SHKConfig.h:

 #include "MyAppInfo.h"
#define SHKMyAppName    MyAppName // define MyAppName elsewhere
  

И в MapAppInfo.h:

 #define MyAppName "Bla bla"
  

Или…

В SHKConfig.h:

 #define SHKMyAppName    MyAppName // define MyAppName elsewhere
  

И в настройках компилятора приложения добавьте:

 -DMyAppName="Bla bla"
  

Комментарии:

1. Это верно, но не имеет ничего общего с исходной проблемой: получить какую-то оценку во время выполнения инструкции #define в сторонней библиотеке.

2. Прочитайте еще раз — слово «среда выполнения» ни разу не упоминалось в вопросе. Заявленная проблема заключалась в том, что «Я не хочу жестко кодировать эти переменные в этом конкретном файле». Кроме того, как вы знаете, #define обрабатывается во время компиляции, а не во время выполнения.

3. Тот факт, что в вопросе отсутствуют некоторые слова, не меняет для меня его смысла. Я действительно думаю, что stackoverflow должен быть местом, где люди стремятся помогать друг другу, а не просто автоматически отвечать на вопросы, даже не пытаясь вникнуть в проблему.

4. @Anton, я согласен с @Danny. Я никогда не упоминал время выполнения в своем вопросе, и он правильно ответил на мой первоначальный вопрос, хотя вы предоставили решение, которое сработало лучше для меня; поэтому я не знаю, стоило ли голосовать против. Я собираюсь предоставить @Anton принятое решение, потому что оно предоставило ответ, о котором я изначально не думал, но оказалось, что он лучше подходит для моей проблемы. Если это не соответствует рекомендациям SO, пожалуйста, дайте мне знать, и я исправлю. Спасибо!!!!

5. Извините, я действительно думал, что Анджело имел в виду то, что я понял.