在 Swift 中使用编译器变量

Posted

技术标签:

【中文标题】在 Swift 中使用编译器变量【英文标题】:Using compiler variables in Swift 【发布时间】:2015-01-06 17:48:37 【问题描述】:

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

标志 => -DPortNumber = 1

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

这在 Swift 中不起作用,我找不到答案。

【问题讨论】:

【参考方案1】:

C 编译器的-D 标志定义了一个预处理器宏。 Swift 中没有预处理器宏。因此,如果您想做类似的事情:

// compile with -DPORT_NUMBER 31337
var port = PORT_NUMBER    // error

...你不能。 Swift 旨在使源代码在编译之前在语法上完整。如果您可以在构建时切换它的块,您将破坏工具链帮助验证您的代码是否正确的能力。 (部分原因是因为 C 中的预处理器宏是文本替换:您可以使用它们重写语言的任何部分,而不仅仅是填充变量的值。)

Swift 编译器确实有一个-D 标志,但它的使用受到更多限制:您只能将它用于build configurations。所以,如果你想做如下的事情,你会很酷:

// compile with -DUSE_STAGING_SERVER
#if USE_STAGING_SERVER
var port = 31337
#else
var port = 80
#endif

请注意,与 C 不同,#if 块中的所有内容都需要在语法上完整。 (例如,您不能只将 func 的声明行放在 #if 块中,而将函数体留在条件之外。)

当然,如果您想在代码中使用在编译时设置的配置,这对您没有帮助。为此,我建议使用其他方法。 Xcode 仍然可以在资源文件中进行文本替换,比如属性列表。 (请注意,您的应用程序附带的 Info.plist 中充满了诸如 $(TARGET_NAME) 之类的内容。)因此,您可以在您的应用程序中包含一个捆绑资源,其内容在编译时根据您的项目设置填充,然后从中读取您的端口号。

【讨论】:

那么有没有可能让一个像“MY_VALUE”这样的 CI 传递一个用户定义的值,它会在 .plist 中被引用并且可以从 Swift 中读取? 对——如果你在 plist 中有类似 someKey = $(MY_VALUE) 的东西(嗯,但是在 XML 中),构建系统将填写 MY_VALUE。 (看看你的模板项目附带的 Info.plist——一些东西,比如包名就是这样定义的。)然后从 plist 加载值的 Swift 代码将获得构建系统定义的值。

以上是关于在 Swift 中使用编译器变量的主要内容,如果未能解决你的问题,请参考以下文章

从 Objective-C 桥接到 swift 时,swift 编译器如何识别变量是复制的还是强的?

我应该如何在 Swift 中的标签中获取变量?

常量与变量

Objc 代码找不到 swift 中定义的 Bool 变量

无法使用 Xcode 7.3.1 在我的 Swift 2 项目中检查带有“po”的变量 - 加载辅助函数时出错

Objective-C和Swift实现单例的几种方式