За відсутності макросів препроцесора, чи існує спосіб визначення практичних схем конкретних прапорів на рівні проекту в проекті Xcode


174

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

Здається, що цей тип конфігураційного гратування не так простий за допомогою швидкого, оскільки макроси не підтримуються. Чи може хтось запропонувати порівняльний підхід, мені байдуже, чи код складений, як такий. Хоча я хотів би передати функції воріт на основі схеми збірки.

Відповіді:


468

У Swift ви все ще можете використовувати макроси препроцесора "# if / # else / # endif" (хоча і більш обмежені), відповідно до документів Apple . Ось приклад:

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

Тепер ви повинні встановити символ "DEBUG" в іншому місці. Встановіть його у розділі "Швидкий компілятор - Спеціальні прапори", рядок "Інші прапорці". Ви додаєте символ DEBUG із -D DEBUGзаписом.

(Налаштування збірки -> Компілятор Swift - Спеціальні прапори) введіть тут опис зображення

Як завжди, ви можете встановити інше значення, коли ви налагоджуєтесь або коли випускаєте.

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


5
Зауважте, що ви також можете використовувати #elseif рядки, щоб додати більше тестів. Досить цікаво, що ви можете отримати доступ до визначення, але нічого не витягувати з нього; тобто визначте -DDEBUG = 5 (або = "FOO"), а потім спробуйте роздрукувати його за допомогою "println (DEBUG is (DEBUG)"). Цей рядок не створює помилок, але нічого не робить
David H

10
Примітка: "Вбудовані налаштування -> Швидкий компілятор -> Спеціальні прапори" не відображаються в "Основних" настройках збірки. Потрібно показати налаштування "Усі" для збирання налаштувань.
levibostian

7
@EugeneDubinin, ймовірно, тому що ви повинні переконатися, що $(inherited)він використовується в цільових налаштуваннях для успадкування налаштувань проекту.
DanSkeel

2
@DanSkeel приємний улов, додаючи $(inherited)робить мій коментар нерелевантним, дякую!
Євген Дубінін

10
У Xcode 8 тепер є також "Активні умови компіляції" у розділі "Швидкий компілятор - Спеціальні прапори". Ви можете додати тут прапори, не потребуючи -D
Marcus

32

Ми зіткнулися з проблемою, не бажаючи встановлювати прапорці швидкого компілятора, оскільки нам не хотілося їх встановлювати та оновлювати їх для різних цілей тощо. Також у нашій змішаній кодовій базі ми не хотіли згадувати щоб встановити наші прапори відповідним чином весь час для кожної мови.

Для нашого ми оголосили файл в 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")
}

Це, безумовно, рішення, але це вирішило нашу проблему, тому я розмістив її тут, сподіваючись, що це допоможе. Це не означає, що можна припустити, що відповіді недійсні.


11
Вся суть макросів полягає в зміні коду на основі конфігурації збірки. Ви повертаєте if до часу виконання, для цього вам не потрібні макроси.
Берік

18
@ 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
}

1

Для мене встановіть пункт налагодження " Умова активної компіляції " на "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

0

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

  1. Я створив метод класу на одному з моїх класів obj-c, який є обгорткою навколо цього макросу.
  2. Я додав цей заголовок obj-c до нашого файлу заголовка мосту.
  3. Тепер мій швидкий код називає цей метод класу "проксі" макросом obj-c.

Легко дратує те, що я не можу просто викликати макрос прямо в швидкому коді, але принаймні зараз у мене є лише одне місце в проекті, щоб хвилюватися про ввімкнення / вимкнення мого прапора налагодження.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.