在Swift中使用编译器变量

9

在Objective-C中,我在“构建设置 -> 其他C标志”中设置了一堆编译器标志,这些标志在代码中被使用。例如:

标志 => -DPortNumber = 1

在代码中,我可以通过@(PortNumber)来访问它。

在Swift中,这种方法行不通,我找不到答案。

1个回答

16
C编译器的-D标志定义了一个预处理宏。在Swift中没有预处理宏。所以如果你想做类似这样的事情:
// compile with -DPORT_NUMBER 31337
var port = PORT_NUMBER    // error

...你做不到。Swift是设计成在编译之前源代码是语法上完整的。如果你可以在构建时切换其中的代码块,那么就会破坏工具链帮助验证代码正确性的能力。(部分原因是因为C中的预处理宏是文本替换:你可以使用它们重写语言的任何部分,而不仅仅是为变量填充值。)
Swift编译器确实有一个-D标志,但它的使用更有限:你只能在构建配置中使用它。所以,如果你想做类似下面的事情,那就没问题:
// compile with -DUSE_STAGING_SERVER
#if USE_STAGING_SERVER
var port = 31337
#else
var port = 80
#endif

请注意,与C语言不同,#if块中的所有内容都需要在语法上完整。例如,你不能只在#if块中放置func的声明行,然后将函数体放在条件之外。
当然,如果你想在编译时使用配置,这并不能帮到你。对此,我建议采用其他方法。Xcode仍然可以在资源文件中进行文本替换,比如属性列表。 (请注意,你的应用程序附带的Info.plist中充满了像$(TARGET_NAME)这样的内容。)因此,你可以在应用程序中包含一个bundle资源,其内容根据编译时的项目设置进行填充,然后从中读取端口号。

那么是否可以通过 CI 传递一个用户定义的值,例如 "MY_VALUE",并在 .plist 中引用它以便从 Swift 中读取? - Fawkes
如果你在 plist 文件中有类似 someKey = $(MY_VALUE) 的内容(当然,这是在 XML 中),构建系统将会填充 MY_VALUE。(看一下模板项目附带的 Info.plist 文件,像 bundle 名称之类的东西就是这样定义的。)然后,从 plist 文件中加载值的 Swift 代码将会获取到构建系统定义的值。 - rickster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接