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

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

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

7 ответов

Решение

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

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

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

(Настройки сборки -> Swift Compiler - Пользовательские флаги)

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

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

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

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

PreProcessorMacros.h

extern BOOL const DEBUG_BUILD;

В них

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")
}

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

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

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

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

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

if isDebugMode {
    // Do debug stuff
}

Для меня установка пункта отладки "Условия активной компиляции" на "DEBUG" сработала.

Затем с использованием ключа DEBGU работа в #IF DEBUG работает в режиме отладки и #ELSE в режиме выпуска:

  1. Выберите свою цель,
  2. На вкладке "Параметры сборки" найдите "Условия активной компиляции",
  3. Установите для его элемента "Отладка" значение "YourKeyWord",
  4. Используйте просто следующим образом:

    #if DEBUG
        print("You'r running in DEBUG mode!")
    #else
        print("You'r running in RELEASE mode!")
    #endif
    

Все отличные ответы

Я хочу добавить, что если вы хотите создавать свои собственные более сложные макросы (как, например, в C++), я предлагаю изучить фрагменты кода.

Вы можете использовать автозаполнение, используя уже существующие заполнители:

      #if DEBUG
<#DEBUGCODE#>
#else
#error("Not for Release!")
#endif

ГдеСоздает заполнитель для заполнения

Директивы компилятора Swift

Вы можете использовать следующую директиву компилятора

      #if <some_key>
    //logic 1
#else
    //logic 2
#endif
      //pre Xcode v8
Other Swift Flags(OTHER_SWIFT_FLAGS) = -D <some_key>
-D DEBUG

//from Xcode v8
Active Compilation Conditions(SWIFT_ACTIVE_COMPILATION_CONDITIONS) = <some_key>
DEBUG

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

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

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

Другие вопросы по тегам