本文翻译自:#ifdef replacement in the Swift language

In C/C++/Objective-C you can define a macro using compiler preprocessors. 在C / C ++ / Objective-C中,您可以使用编译器预处理程序定义宏。 Moreover, you can include/exclude some parts of code using compiler preprocessors. 此外,您可以使用编译器预处理程序包含/排除部分代码。

#ifdef DEBUG// Debug-only code
#endif

Is there a similar solution in Swift? Swift中有类似的解决方案吗?


#1楼

参考:https://stackoom.com/question/1ciLr/Swift语言中的-ifdef替换


#2楼

There is no Swift preprocessor. 没有Swift预处理器。 (For one thing, arbitrary code substitution breaks type- and memory-safety.) (一方面,任意代码替换都会破坏类型和内存安全性。)

Swift does include build-time configuration options, though, so you can conditionally include code for certain platforms or build styles or in response to flags you define with -D compiler args. 但是,Swift确实包含了构建时配置选项,因此您可以有条件地包含某些平台或构建样式的代码,或者响应使用-D编译器args定义的标志。 Unlike with C, though, a conditionally compiled section of your code must be syntactically complete. 但是,与C语言不同,代码的条件编译部分必须在语法上完整。 There's a section about this in Using Swift With Cocoa and Objective-C . 在Swift与Cocoa和Objective-C结合使用中有关于这一部分的内容。

For example: 例如:

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

#3楼

Yes you can do it. 是的,你可以做到。

In Swift you can still use the "#if/#else/#endif" preprocessor macros (although more constrained), as per Apple docs . 在Swift中,按照Apple docs的规定 ,您仍然可以使用“#if /#else /#endif”预处理器宏(尽管有更多限制)。 Here's an example: 这是一个例子:

#if DEBUGlet a = 2
#elselet a = 3
#endif

Now, you must set the "DEBUG" symbol elsewhere, though. 现在,您必须在其他位置设置“ DEBUG”符号。 Set it in the "Swift Compiler - Custom Flags" section, "Other Swift Flags" line. 在“ Swift编译器-自定义标志”部分的“其他Swift标志”行中进行设置。 You add the DEBUG symbol with the -D DEBUG entry. 您将DEBUG符号与-D DEBUG条目一起添加。

As usual, you can set a different value when in Debug or when in Release. 与往常一样,您可以在Debug或Release中设置不同的值。

I tested it in real code and it works; 我用真实代码对其进行了测试,并且可以正常工作。 it doesn't seem to be recognized in a playground though. 它似乎在操场上似乎未被认可。

You can read my original post here . 您可以在这里阅读我的原始帖子。


IMPORTANT NOTE: -DDEBUG=1 doesn't work. 重要说明: -DDEBUG=1不起作用。 Only -D DEBUG works. -D DEBUG有效。 Seems compiler is ignoring a flag with a specific value. 似乎编译器正在忽略具有特定值的标志。


#4楼

In many situations, you don't really need conditional compilation ; 在很多情况下,您实际上并不需要条件编译 you just need conditional behavior that you can switch on and off. 您只需要可以打开和关闭的条件行为即可。 For that, you can use an environment variable. 为此,您可以使用环境变量。 This has the huge advantage that you don't actually have to recompile. 这具有巨大的优势,您实际上不必重新编译。

You can set the environment variable, and easily switch it on or off, in the scheme editor: 您可以在方案编辑器中设置环境变量,并轻松地将其打开或关闭:

You can retrieve the environment variable with NSProcessInfo: 您可以使用NSProcessInfo检索环境变量:

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

Here's a real-life example. 这是一个真实的例子。 My app runs only on the device, because it uses the music library, which doesn't exist on the Simulator. 我的应用程序仅在设备上运行,因为它使用的音乐库在模拟器上不存在。 How, then, to take screen shots on the Simulator for devices I don't own? 那么,如何在模拟器上为我不拥有的设备拍摄屏幕截图? Without those screen shots, I can't submit to the AppStore. 没有这些屏幕截图,我将无法提交到AppStore。

I need fake data and a different way of processing it . 我需要伪造数据其他处理方式 I have two environment variables: one which, when switched on, tells the app to generate the fake data from the real data while running on my device; 我有两个环境变量:一个在打开时告诉应用程序在设备上运行时从真实数据生成假数据; the other which, when switched on, uses the fake data (not the missing music library) while running on the Simulator. 另一种是在模拟器上运行时打开时使用伪造的数据(而不是缺少的音乐库)。 Switching each of those special modes on / off is easy thanks to environment variable checkboxes in the Scheme editor. 通过使用方案编辑器中的环境变量复选框,可以轻松打开/关闭这些特殊模式。 And the bonus is that I can't accidentally use them in my App Store build, because archiving has no environment variables. 而且好处是,我不会在App Store构建中意外使用它们,因为归档没有环境变量。


#5楼

As of Swift 4.1, if all you need is just check whether the code is built with debug or release configuration, you may use the built-in functions: 从Swift 4.1开始,如果只需要检查代码是使用调试还是发布配置构建的,则可以使用内置函数:

  • _isDebugAssertConfiguration() (true when optimization is set to -Onone ) _isDebugAssertConfiguration() (当优化设置为-Onone时为-Onone
  • _isReleaseAssertConfiguration() (true when optimization is set to -O ) _isReleaseAssertConfiguration() (将优化设置为-O时为true) (not available on Swift 3+) (不适用于Swift 3+)
  • _isFastAssertConfiguration() (true when optimization is set to -Ounchecked ) _isFastAssertConfiguration() (当优化设置为-Ounchecked时为-Ounchecked

eg 例如

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

Compared with preprocessor macros, 与预处理器宏相比,

  • ✓ You don't need to define a custom -D DEBUG flag to use it ✓您无需定义自定义-D DEBUG标志即可使用它
  • ~ It is actually defined in terms of optimization settings, not Xcode build configuration 〜实际上是根据优化设置而不是Xcode构建配置定义的
  • ✗ Undocumented, which means the function can be removed in any update (but it should be AppStore-safe since the optimizer will turn these into constants) ✗未记录,这意味着该功能可以在任何更新中删除(但它应该是AppStore安全的,因为优化程序会将其转换为常量)

    • these once removed , but brought back to public to lack of @testable attribute , fate uncertain on future Swift. 这些曾经被删除 ,但由于缺乏@testable属性而重新公开 ,命运对未来的Swift不确定。
  • ✗ Using in if/else will always generate a "Will never be executed" warning. in在in / if / else中使用将始终生成“将永远不会执行”警告。


#6楼

As stated in Apple Docs 如Apple Docs中所述

The Swift compiler does not include a preprocessor. Swift编译器不包含预处理器。 Instead, it takes advantage of compile-time attributes, build configurations, and language features to accomplish the same functionality. 相反,它利用编译时属性,构建配置和语言功能来实现相同的功能。 For this reason, preprocessor directives are not imported in Swift. 因此,预处理器指令不会导入Swift中。

I've managed to achieve what I wanted by using custom Build Configurations: 通过使用自定义构建配置,我设法实现了想要的目标:

  1. Go to your project / select your target / Build Settings / search for Custom Flags 转到项目/选择目标/构建设置/搜索自定义标志
  2. For your chosen target set your custom flag using -D prefix (without white spaces), for both Debug and Release 对于所选目标,使用-D前缀(不带空格)设置调试和发布的自定义标志
  3. Do above steps for every target you have 对您拥有的每个目标执行上述步骤

Here's how you check for target: 检查目标的方法如下:

#if BANANAprint("We have a banana")
#elseif MELONAprint("Melona")
#elseprint("Kiwi")
#endif

Tested using Swift 2.2 使用Swift 2.2测试

Swift语言中的#ifdef替换相关推荐

  1. ​Swift语言中为外部参数设置默认值可变参数常量参数变量参数输入输出参数

    ​Swift语言中为外部参数设置默认值可变参数常量参数变量参数输入输出参数 7.4.4  为外部参数设置默认值 开发者也可以对外部参数设置默认值.这时,调用的时候,也可以省略参数传递本文选自Swift ...

  2. Swift语言中如何使用JSON数据教程

    原文:Swift语言中如何使用JSON数据教程 这是一篇翻译文章,原文出处:http://www.raywenderlich.com/82706/working-with-json-in-swift- ...

  3. Swift语言中的感叹号是什么意思?

    本文翻译自:What does an exclamation mark mean in the Swift language? The Swift Programming Language guide ...

  4. 在 Swift 语言中更好的处理 JSON 数据:SwiftyJSON

    SwiftyJSON能够让在Swift语言中更加简便处理JSON数据. With SwiftyJSON all you have to do is: ? 1 2 3 4 let json = JSON ...

  5. 【R语言中如何去除替换NA相关操作】

    R语言中如何去除替换NA相关操作 1.去除矩阵所有含NA的行 2.去除矩阵特定列中含NA的行 3.替换矩阵中的NA值为0 4.将矩阵中某一列的特殊值替换为NA 1.去除矩阵所有含NA的行 data=n ...

  6. Swift语言中的控制语句和函数

    前面说了swift的语法不专门来讲,因为专门学语法会感觉比较无聊,所以就穿插来讲,在讲界面和效果一段时间,又讲一下语法,这样或许会好点. 这里就来讲Swift中的控制语句和函数. 控制语句 控制语句是 ...

  7. C语言中-条件编译#ifdef的妙用详解_透彻

    本文主要介绍c语言中条件编译相关的预编译指令,包括  #define.#undef.#ifdef.#ifndef.#if.#elif.#else.#endif.defined. #define     ...

  8. c语言字符串替换问题,C语言中的字符串替换

    输入参数:char* search 需要搜索的字符串 char* replace 被替换的字符串 char* str 原始字符串 返回 char* 用完后用free()释放 [codesyntax l ...

  9. 使用swift语言进行IOS应用开发

    在Swift中能够直接使用Objective-C语言提供的api (包括系统框架与自己的定制代码),也能够在Objective-C中使用Swift提供的类和api ,还能够在一个工程中同时混合使用Sw ...

最新文章

  1. ios 设置tableview左滑删除按钮的相关属性
  2. linux下使用inotify实时监控文件变更,做完整性检查
  3. 采购计算机的,如何采购计算机
  4. Svchost.exe占用CPU100%全面解析与进程说明
  5. linux下Mplayer安装与设置指南(以及如何加载显示中文字幕)
  6. 按键 使用WinHttp实现POST方式用户模拟登录网站
  7. mysql用户数据导入_mysql创建数据库、用户及导入数据_mysql数据库教程
  8. HDU-1753-大明A+B
  9. 被国人误传了几千年的八句俗语
  10. html小作业--新闻栏目
  11. SI4438系列模块调试
  12. 微信小程序点击事件传递自定义参数的方法和跨页面传递数据
  13. 详解机器学习/深度学习中的梯度消失/梯度爆炸的原因/解决方案
  14. 网易云音乐修改名字怎么老是服务器错误,网易云音乐为什么改了名字?网抑云是怎么回事...
  15. 2022考研复习第八周
  16. 波士顿地区Airbnb价格预测Project (一)
  17. ubuntu conda 更新、下载模块包权限问题 'Permission denied'
  18. 金融投资之重要财务指标 (From Corporate Finance, 6th Edition) 与Tushare数据接口
  19. Xib与Nib区别联系
  20. 软件测试工程师如何优雅的“甩锅”

热门文章

  1. Directory monitor
  2. 【oracle】changePerm.sh
  3. mysql的压缩版安装
  4. [bzoj1008][HNOI2008]越狱-题解[简单组合数学]
  5. JAVA WEB 对返回数据进行按中文名称首字母A~Z升序排序
  6. pivotx的entry和page内容里的日期格式修改
  7. 用C#製作PDF文件全攻略
  8. 全面分析男性护肤三大误区 - 生活至上,美容至尚!
  9. 局域网中服务器群配置ssh免密
  10. Zabbix---1 监控主机磁盘空间