В отсутствие макросов препроцессора, есть ли способ определить конкретные флаги конкретной схемы на уровне проекта в проекте XCode

159

Перед быстрым я бы определил набор схем для альфа-версий, бета-версий и дистрибутивов. Каждая из этих схем имела бы набор макросов, которые были определены для предотвращения определенных типов поведения на уровне проекта. Самый простой пример - макрос DEBUG = 1, который по умолчанию задан для всех проектов Xcode в схеме по умолчанию для сборки Run. Можно было бы запросить #ifdef DEBUG... и принять решения в коде соответственно, даже составив ненужный код.

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

Теги:

4 ответа

431
Лучший ответ

В Swift вы все равно можете использовать макросы препроцессора "# if/# else/# endif" (хотя и более ограниченные), согласно Apple docs. Вот пример:

#if DEBUG
    let a = 2
#else
    let a = 3
#endif

Теперь вы должны установить символ "DEBUG" в другом месте. Установите его в разделе "Swift Compiler - Custom Flags", "Other Swift Flags". Вы добавляете символ DEBUG с записью -D DEBUG.

(Настройки сборки → Быстрый компилятор - Пользовательские флаги) Изображение 1820

Как обычно, вы можете установить другое значение в Debug или в Release.

Я тестировал его в реальном коде; он, похоже, не распознается на детской площадке.

  • 5
    Обратите внимание, что вы также можете использовать строки #elseif для добавления дополнительных тестов. Интересно, что вы можете получить доступ к определению, но ничего не извлечь из него; то есть, определите -DDEBUG = 5 (или = "FOO"), а затем попытайтесь напечатать его с помощью "println (DEBUG is (DEBUG)"). Эта строка не генерирует ошибок, но ничего не делает.
  • 0
    Обратите внимание, что, как утверждает @Jean, ключевым аспектом этого является добавление параметра в «Swift Compiler - Custom Flags». Я установил их (пережиток первоначального проекта Obj-C) в разделе предварительной обработки LLVM. Интересно , что секция LLVM действительно добавляет запись к быстрой командной строке, но как «-DFlag», но при добавлении «-DFlag» в раздел «Других Swift флаги» он чудесным образом меняет флаг «-Д флаг» на быстрая командная строка. Это последнее поведение кажется ключевым. Так много для последовательности ...
Показать ещё 10 комментариев
27

Мы столкнулись с проблемой, не желая устанавливать быстрые флаги компилятора, потому что мы не хотели устанавливать их и поддерживать их в актуальном состоянии для разных целей и т.д. Кроме того, в нашей смешанной кодовой базе мы не хотели чтобы не забывать постоянно устанавливать флаги для каждого языка.

Для наших мы объявили файл в ObjC

PreProcessorMacros.h

extern BOOL const DEBUG_BUILD;

В .m

PreProcessorMacros.m

#ifdef DEBUG
    BOOL const DEBUG_BUILD = YES;
#else
    BOOL const DEBUG_BUILD = NO;
#endif

Затем в Objective-C заголовок заголовка

#import "PreProcessorMacros.h"

Теперь, используйте это в своей кодовой базе Swift

if DEBUG_BUILD {
    println("debug")
} else {
    println("release")
}

Это, безусловно, обходной путь, но он решил нашу проблему, поэтому я разместил ее здесь в надежде, что это поможет. Это не означает, что существующие ответы недействительны.

  • 11
    Весь смысл макросов в том, чтобы изменить код в зависимости от конфигурации сборки. Вы возвращаете if во время выполнения, для этого вам не нужны макросы.
  • 16
    @Berik - я опубликовал правильное решение в надежде, что оно может также помочь другим, пытающимся решить аспект этой проблемы, особенно в многоязычных проектах. Если ваша проблема не требует компиляции определенного кода, это нормально. Также замечателен комментарий, особенно когда он разъясняет некоторым, почему это не может быть решением для них. Также просим сделать отметку в ответе об ограничениях этого подхода. Понижающее голосование является ненужным и препятствует альтернативным решениям, которые могут быть полезны для других, решающих подобные проблемы. Кроме того, оп говорит: «Мне все равно, если код скомпилирован».
5

Более быстрое решение для метода Logans. Установите -D DEBUG в Other Swift Flags раздела Swift Compiler - Custom Flags в настройках сборки вашей цели.

Затем объявите следующий метод в глобальной области:

#if DEBUG
let isDebugMode = true
#else
let isDebugMode = false
#endif

Теперь используйте его как

if isDebugMode {
    // Do debug stuff
}
0

Я работаю в базе кода смешанного языка, где код obj-c использует макрос для отправки отладочных сообщений на консоль (и этот макрос полагается на наш флаг препроцессора отладки). Я хотел иметь возможность вызвать тот же самый макрос в быстром коде...

  • Я создал метод класса на одном из моих классов obj-c, который является оберткой вокруг этого макроса.
  • Я добавил заголовок obj-c в наш файл заголовка моста.
  • Теперь мой быстрый код вызывает этот метод класса как "прокси" для макроса obj-c.

Мягко раздражает, что я не могу просто вызвать макрос прямо в быстром коде, но по крайней мере сейчас у меня есть только одно место в проекте, чтобы беспокоиться о включении/отключении флага отладки.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню