在C/C++/Objective C中,可以使用编译器预处理器定义宏。此外,您可以使用编译器预处理器包含/排除代码的某些部分。

#ifdef DEBUG
    // Debug-only code
#endif

Swift中有类似的解决方案吗?


当前回答

马特回答的Swift 5更新

let dic = ProcessInfo.processInfo.environment
if dic["TRIPLE"] != nil {
// ... do your secret stuff here ...
}

其他回答

如Apple Docs中所述

Swift编译器不包含预处理器。相反,它利用编译时属性、构建配置和语言特性来实现相同的功能。因此,在Swift中不导入预处理器指令。

我已经通过使用自定义构建配置实现了我想要的目标:

转到项目/选择目标/构建设置/搜索自定义标志对于所选目标,使用-D前缀(不带空格)为调试和发布设置自定义标志为您的每个目标执行以上步骤

以下是检查目标的方法:

#if BANANA
    print("We have a banana")
#elseif MELONA
    print("Melona")
#else
    print("Kiwi")
#endif

使用Swift 2.2测试

从Swift 4.1开始,如果你只需要检查代码是用调试还是发布配置构建的,你可以使用内置函数:

_isDebugAssertConfiguration()(当优化设置为-Onone时为true)_isReleaseAssertConfiguration()(当优化设置为-O时为true)(在Swift 3+上不可用)_isFastAssertConfiguration()(当优化设置为-Ounchecked时为true)

e.g.

func obtain() -> AbstractThing {
    if _isDebugAssertConfiguration() {
        return DecoratedThingWithDebugInformation(Thing())
    } else {
        return Thing()
    }
}

与预处理器宏相比,

✓ 您不需要定义自定义的-D DEBUG标志来使用它~它实际上是根据优化设置定义的,而不是Xcode构建配置✗ 未记录,这意味着该函数可以在任何更新中删除(但它应该是AppStore安全的,因为优化器会将这些转换为常量)这些内容一度被删除,但由于缺少@testable属性而重新公开,未来的Swift命运未卜。✗ 在if/else中使用将始终生成“将永远不会执行”警告。

莫伊尼昂的回答很好。这是另一条信息,以防有帮助,

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

您可以像下面这样否定宏,

#if !RELEASE
    let a = 2
#else
    let a = 3
#endif

在GCC_PREPROCESSOR_DEFINITIONS构建设置中设置DEBUG=1后,我更喜欢使用函数进行以下调用:

func executeInProduction(_ block: () -> Void)
{
    #if !DEBUG
        block()
    #endif
}

然后,只需在此函数中包含我希望在调试构建中省略的任何块:

executeInProduction {
    Fabric.with([Crashlytics.self]) // Compiler checks this line even in Debug
}

与以下各项相比的优势:

#if !DEBUG
    Fabric.with([Crashlytics.self]) // This is not checked, may not compile in non-Debug builds
#endif

是编译器检查我的代码的语法,所以我确信它的语法是正确的,并进行编译。

马特回答的Swift 5更新

let dic = ProcessInfo.processInfo.environment
if dic["TRIPLE"] != nil {
// ... do your secret stuff here ...
}