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

#ifdef DEBUG
    // Debug-only code
#endif

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


当前回答

在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

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

其他回答

在使用Xcode版本9.4.1创建的Swift项目中,Swift 4.1

#if DEBUG
#endif

默认情况下工作,因为在预处理器宏中,Xcode已设置DEBUG=1。

因此,您可以使用#if DEBUG“开箱即用”。

顺便说一句,苹果的《Swift编程语言4.1》一书(编译器控制语句一节)中写了如何使用条件编译块,而如何编写编译标志以及Swift中C宏的对应内容,则在另一本苹果的《将Swift与Cocoa和Objective C结合使用》一书中(预处理器指令一节)

希望未来苹果会为他们的书写更详细的内容和索引。

我的两分钱用于Xcode 8:

a) 使用-D前缀的自定义标志工作正常,但。。。

b) 更简单的使用:

在Xcode 8中有一个新的部分:“活动编译条件”,已经有两行,用于调试和发布。

只需添加无D的定义。

在许多情况下,您实际上不需要条件编译;您只需要可以打开和关闭的条件行为。为此,您可以使用环境变量。这有一个巨大的优点,你实际上不需要重新编译。

您可以在方案编辑器中设置环境变量,并轻松地将其打开或关闭:

您可以使用NSProcessInfo检索环境变量:

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

这是一个现实生活中的例子。我的应用程序只在设备上运行,因为它使用的是模拟器上不存在的音乐库。那么,如何在模拟器上拍摄我不拥有的设备的屏幕快照?没有这些屏幕截图,我无法提交到AppStore。

我需要假数据和不同的处理方式。我有两个环境变量:一个是当打开时,告诉应用程序在我的设备上运行时从真实数据生成假数据;另一个,当打开时,在模拟器上运行时使用假数据(而不是丢失的音乐库)。由于Scheme编辑器中的环境变量复选框,打开/关闭这些特殊模式很容易。另外一个好处是,我不会在我的App Store构建中意外使用它们,因为归档没有环境变量。

Xcode 8对ifdef替换进行了重大更改。即使用主动编译条件。

请参阅Xcode 8发行说明中的构建和链接。

新建生成设置

新设置:SWIFT_ACTIVE_COMPILATION_CONDITIONS

“Active Compilation Conditions” is a new build setting for passing conditional compilation flags to the Swift compiler.

以前,我们必须在OTHER_SWIFT_flags下声明条件编译标志,记住在设置前加上“-D”。例如,要有条件地使用MYFLAG值进行编译:

#if MYFLAG1
    // stuff 1
#elseif MYFLAG2
    // stuff 2
#else
    // stuff 3
#endif

要添加到设置的值-DMYFLAG

现在我们只需要将值MYFLAG传递到新设置。是时候移动所有这些条件编译值了!

有关Xcode 8中更多Swift Build Settings功能,请参阅以下链接:http://www.miqu.me/blog/2016/07/31/xcode-8-new-build-settings-and-analyzer-improvements/

func inDebugBuilds(_ code: () -> Void) {
    assert({ code(); return true }())
}

来源