在没有预处理器宏的情况下,有没有办法在 Xcode 项目的项目级别定义实用的方案特定标志
Posted
技术标签:
【中文标题】在没有预处理器宏的情况下,有没有办法在 Xcode 项目的项目级别定义实用的方案特定标志【英文标题】:In absence of preprocessor macros, is there a way to define practical scheme specific flags at project level in Xcode project 【发布时间】:2014-07-29 11:54:23 【问题描述】:在 swift 之前,我将为 alpha、beta 和分发构建定义一组方案。这些方案中的每一个都将具有一组宏,这些宏被定义为在项目级别控制某些行为。最简单的例子是 DEBUG=1 宏,它是默认为 Run 构建的默认方案中的所有 Xcode 项目定义的。可以查询#ifdef DEBUG ...并在代码中做出相应的决定,甚至编译出不必要的代码。
似乎这种类型的配置门控使用 swift 并不容易,因为不支持宏。有人可以提出一种类似的方法吗,我不在乎代码本身是否被编译出来。不过,我想根据构建方案对功能进行门控。
【问题讨论】:
【参考方案1】:在 Swift 中,您仍然可以使用“#if/#else/#endif”预处理器宏(尽管受到更多限制),如 Apple docs。这是一个例子:
#if DEBUG
let a = 2
#else
let a = 3
#endif
现在,您必须在别处设置“DEBUG”符号。在“Swift Compiler - Custom Flags”部分的“Other Swift Flags”行中设置它。使用 -D DEBUG
条目添加 DEBUG 符号。
(构建设置 -> Swift 编译器 - 自定义标志)
像往常一样,您可以在调试或发布时设置不同的值。
我用真实代码测试过它;在操场上似乎无法识别它。
【讨论】:
请注意,您还可以使用#elseif 行添加更多测试。有趣的是,您可以访问定义但不从中提取任何内容;也就是说,定义 -DDEBUG=5(或 ="FOO"),然后尝试使用“println(DEBUG is (DEBUG)”打印它。该行不会产生错误,但不会执行任何操作。 注意:“内置设置 -> Swift 编译器 -> 自定义标志”在“基本”构建设置中不可见。必须显示“所有”构建设置才能显示。 @EugeneDubinin 可能是因为您应该确保在目标设置中使用$(inherited)
以继承项目设置。
@DanSkeel 很好,添加$(inherited)
使我的评论无关紧要,谢谢!
在 Xcode 8 中,“Swift 编译器 - 自定义标志”部分现在还有一个“活动编译条件”设置。您可以在此处添加标志而无需 -D【参考方案2】:
我们遇到了不想设置 swift 编译器标志的问题,因为我们不想设置它们并让它们针对不同的目标等保持最新。此外,在我们的混合代码库中,我们不希望记住要始终为每种语言适当地设置我们的标志。
对于我们来说,我们在 ObjC 中声明了一个文件
PreProcessorMacros.h
extern BOOL const DEBUG_BUILD;
在.m中
PreProcessorMacros.m
#ifdef DEBUG
BOOL const DEBUG_BUILD = YES;
#else
BOOL const DEBUG_BUILD = NO;
#endif
然后,在您的 Objective-C 桥接头中
#import "PreProcessorMacros.h"
现在,在你的 Swift 代码库中使用它
if DEBUG_BUILD
println("debug")
else
println("release")
这绝对是一种解决方法,但它解决了我们的问题,所以我在这里发布它希望它会有所帮助。这并不意味着现有的答案是无效的。
【讨论】:
宏的重点是根据构建配置更改代码。您将 if 带回运行时,您不需要宏。 @Berik - 我发布了一个有效的解决方案,希望它也可以帮助其他人尝试解决这个问题的某个方面,特别是在多语言项目中。如果您的问题不需要编译特定代码,那很好。评论也很好,特别是当它教育一些为什么这可能不是他们的解决方案时。还要求在答案中注明这种方法的局限性。投票是不必要的,并且不鼓励可能有助于其他人解决类似问题的替代解决方案。另外,op 说“我不在乎代码是否被编译出来”。【参考方案3】:Logans 方法更快速的解决方案。在目标的构建设置中的Swift Compiler - Custom Flags
部分的Other Swift Flags
中设置-D DEBUG
。
然后在全局范围内声明如下方法:
#if DEBUG
let isDebugMode = true
#else
let isDebugMode = false
#endif
现在使用它
if isDebugMode
// Do debug stuff
【讨论】:
【参考方案4】:对我来说,将“Active Compilation Condition”的调试项设置为“DEBUG”即可。
然后在#IF DEBUG 中使用DEBGU 键在调试模式下工作,在发布模式下使用#ELSE:
-
选择你的目标,
在 Build Setting 选项卡中搜索“Active Compilation Condition”,
将其“Debug”项的值设置为“YourKeyWord”,
使用简单如下:
#if DEBUG
print("You'r running in DEBUG mode!")
#else
print("You'r running in RELEASE mode!")
#endif
【讨论】:
【参考方案5】:我正在使用混合语言代码库,其中 obj-c 代码使用宏将调试消息发送到控制台(并且该宏依赖于我们的调试预处理器标志)。我希望能够在 swift 代码中调用相同的宏...
-
我在我的一个 obj-c 类上创建了一个类方法,它是该宏的包装器。
我将那个 obj-c 头文件添加到我们的桥头文件中。
现在我的 swift 代码将该类方法调用为 obj-c 宏的“代理”。
我不能在 swift 代码中直接调用宏,这有点烦人,但至少现在我在项目中只有一个地方需要担心打开/关闭我的调试标志。
【讨论】:
以上是关于在没有预处理器宏的情况下,有没有办法在 Xcode 项目的项目级别定义实用的方案特定标志的主要内容,如果未能解决你的问题,请参考以下文章