用Swift语言#ifdefreplace

在C / C ++ / Objective-C中,您可以使用编译器预处理程序定义一个macros。 而且,您可以使用编译器预处理器来包含/排除某些代码部分。

#ifdef DEBUG // Debug-only code #endif 

Swift中是否有类似的解决scheme?

是的,你可以做到这一点。

在Swift中,仍然可以使用“#if /#else /#endif”预处理器macros(尽pipe受到更多限制),按照Apple文档 。 这是一个例子:

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

现在,您必须在别处设置“DEBUG”符号。 将其设置在“Swift编译器 – 自定义标志”部分的“其他Swift标志”行中。 用-D DEBUG条目添加DEBUG符号。

像往常一样,您可以在“debugging”或“发行版”中设置不同的值。

我testing了它在真实的代码,它的工作原理; 它似乎并没有在游乐场被认出。

你可以在这里阅读我原来的文章。


重要说明: -DDEBUG=1不起作用。 只有-D DEBUG才能工作。 似乎编译器正在忽略具有特定值的标志。

正如苹果文档所述

Swift编译器不包含预处理器。 相反,它利用编译时间属性,构buildconfiguration和语言function来实现相同的function。 由于这个原因,预处理器指令不能在Swift中导入。

我已经设法达到我想要的使用自定义生成configuration:

  1. 转到您的项目/select您的目标/构build设置/search自定义标志
  2. 对于您select的目标,使用-D前缀(无空格)设置您的自定义标志,用于debugging和发布
  3. 针对每个目标进行上述步骤

以下是你如何检查目标:

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

在这里输入图像描述

使用Swift 2.2进行testing

在很多情况下,你并不需要有条件的编译 ; 你只需要有条件的行为 ,你可以打开和closures。 为此,您可以使用环境variables。 这具有巨大的优势,您实际上不必重新编译。

您可以设置环境variables,并在scheme编辑器中轻松地打开或closures它:

在这里输入图像描述

您可以使用NSProcessInfo检索环境variables:

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

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

我需要假数据处理它不同方式 。 我有两个环境variables:一个开启时告诉应用程序在我的设备上运行时从真实数据中生成假数据; 另一个在打开时在模拟器上运行时使用假数据(而不是丢失的音乐库)。 通过Scheme编辑器中的环境variablescheckbox可轻松切换每个特殊模式。 而且奖金是我不能在App Store中意外地使用它们,因为归档没有环境variables。

Xcode 8的ifdefreplace的主要变化。即使用活动编译条件

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

新build立设置

新的设置: 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 Settingsfunction: http : //www.miqu.me/blog/2016/07/31/xcode-8-new-build-settings-and-analyzer-improvements/

从Swift 3.1开始,如果您只需要检查代码是否使用debugging或发布configuration构build,则可以使用内置函数:

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

例如

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

与预处理器macros相比,

  • ✓您不需要定义一个自定义的-D DEBUG标志来使用它
  • 〜它实际上是根据优化设置来定义的,而不是Xcode的构buildconfiguration
  • ✗未logging,这意味着该函数可以在任何更新中被删除(但是它应该是AppStore安全的,因为优化器会将它们变成常量)

    • 这些曾经被删除 ,但带回公共缺乏@可@testable属性 ,在Swift 4.0上命运不定
  • ✗使用if / else将始终生成“永不执行”警告。

没有Swift预处理器。 (一方面,任意代码replace破坏了types和内存的安全性。)

不过Swift的确包含了构build时的configuration选项,所以你可以有条件地包含某些平台的代码或构build样式,或者响应你用-D编译器参数定义的标志。 与C不同的是,代码的条件编译部分必须在语法上完整。 在使用Cocoa和Objective-C的Swift中有一部分内容。

例如:

 #if os(iOS) let color = UIColor.redColor() #else let color = NSColor.redColor() #endif 

Xcode 8及以上

使用编译 设置/ Swift编译器中的 活动编译条件设置– 自定义标志

  • 这是将条件编译标志传递给Swift编译器的新的构build设置。
  • 简单的添加这样的标志: ALPHABETA

然后用这样的编译条件检查它:

 #if ALPHA // #elseif BETA // #else // #endif 

提示:您也可以使用#if !ALPHA

我的Xcode 8的两美分:

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

b)使用更简单:

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

只需添加您的定义WITHOUT -D