mxg*_*mxg 697 xcode preprocessor preprocessor-directive swift
在C/C++/Objective-C中,您可以使用编译器预处理器定义宏.此外,您可以使用编译器预处理器包含/排除代码的某些部分.
#ifdef DEBUG
// Debug-only code
#endif
Run Code Online (Sandbox Code Playgroud)
Swift中有类似的解决方案吗?
Jea*_*nan 1020
是的,你可以做到.
在Swift中,您仍然可以使用"#if /#else /#endif"预处理器宏(尽管更受限制),如Apple文档所述.这是一个例子:
#if DEBUG
let a = 2
#else
let a = 3
#endif
Run Code Online (Sandbox Code Playgroud)
现在,您必须在其他位置设置"DEBUG"符号.将它设置在"Swift Compiler - Custom Flags"部分,"Other Swift Flags"行中.您可以使用-D DEBUG条目添加DEBUG符号.
像往常一样,您可以在Debug或Release中设置不同的值.
我在实际代码中测试它并且它工作; 但它似乎并没有在游乐场中得到认可.
你可以在这里阅读我的原帖.
重要说明: -DDEBUG=1不起作用.只有-D DEBUG作品.似乎编译器忽略了具有特定值的标志.
And*_*rej 342
Swift编译器不包含预处理器.相反,它利用编译时属性,构建配置和语言功能来实现相同的功能.因此,预处理程序指令不会在Swift中导入.
我通过使用自定义构建配置设法实现了我想要的目标:
以下是检查目标的方法:
#if BANANA
print("We have a banana")
#elseif MELONA
print("Melona")
#else
print("Kiwi")
#endif
Run Code Online (Sandbox Code Playgroud)
使用Swift 2.2测试
mat*_*att 168
在许多情况下,您并不需要条件编译 ; 你只需要可以打开和关闭的条件行为.为此,您可以使用环境变量.这具有巨大的优势,您实际上不必重新编译.
您可以在方案编辑器中设置环境变量,并轻松打开或关闭它:

您可以使用NSProcessInfo检索环境变量:
let dic = NSProcessInfo.processInfo().environment
if dic["TRIPLE"] != nil {
// ... do secret stuff here ...
}
Run Code Online (Sandbox Code Playgroud)
这是一个真实的例子.我的应用程序仅在设备上运行,因为它使用模拟器上不存在的音乐库.那么,如何在模拟器上为我不拥有的设备拍摄屏幕截图?没有这些屏幕截图,我无法提交到AppStore.
我需要假数据和不同的处理方式.我有两个环境变量:一个在打开时告诉应用程序在我的设备上运行时从真实数据生成虚假数据; 另一个,当打开时,在模拟器上运行时使用假数据(而不是丢失的音乐库).由于Scheme编辑器中的环境变量复选框,可以轻松打开/关闭每个特殊模式.奖金是我不能在我的App Store构建中意外使用它们,因为归档没有环境变量.
DSh*_*hah 152
ifdefXcode 8提出了一个重大的替换更改,即使用Active Compilation Conditions.
请参阅建筑和链接在Xcode中8注版.
新的构建设置
新设置: SWIFT_ACTIVE_COMPILATION_CONDITIONS
“Active Compilation Conditions” is a new build setting for passing conditional compilation flags to the Swift compiler.
Run Code Online (Sandbox Code Playgroud)
以前,我们必须在OTHER_SWIFT_FLAGS下声明您的条件编译标志,记住在设置前加上"-D".例如,要使用MYFLAG值进行有条件的编译:
#if MYFLAG1
// stuff 1
#elseif MYFLAG2
// stuff 2
#else
// stuff 3
#endif
Run Code Online (Sandbox Code Playgroud)
要添加到设置的值 -DMYFLAG
现在我们只需要将值MYFLAG传递给新设置.是时候移动所有这些条件编译值了!
有关Xcode 8中的更多Swift Build Settings功能,请参阅以下链接:http: //www.miqu.me/blog/2016/07/31/xcode-8-new-build-settings-and-analyzer-improvements/
ken*_*ytm 91
从Swift 4.1开始,如果您只需要检查代码是使用调试版还是发布版构建,那么您可以使用内置函数:
_isDebugAssertConfiguration()(当优化设置为时为true -Onone)_isReleaseAssertConfiguration()(当优化设置为时为true -O)_isFastAssertConfiguration()(当优化设置为时为true -Ounchecked)例如
func obtain() -> AbstractThing {
if _isDebugAssertConfiguration() {
return DecoratedThingWithDebugInformation(Thing())
} else {
return Thing()
}
}
Run Code Online (Sandbox Code Playgroud)
与预处理器宏相比,
-D DEBUG标志即可使用它✗未记录,这意味着可以在任何更新中删除该函数(但它应该是AppStore安全的,因为优化器会将这些转换为常量)
@testable属性,未来斯威夫特的命运不确定.✗在if/else中使用将始终生成"永不执行"警告.
Jak*_*lář 84
在Build settings/Swift编译器中使用Active Compilation Conditions设置- 自定义标志.
ALPHA,BETA等等.然后用这样的编译条件检查它:
#if ALPHA
//
#elseif BETA
//
#else
//
#endif
Run Code Online (Sandbox Code Playgroud)
提示:您也可以使用
#if !ALPHA等
ric*_*ter 75
没有Swift预处理器.(一方面,任意代码替换会破坏类型和内存安全性.)
但是,Swift确实包含构建时配置选项,因此您可以有条件地包含某些平台的代码或构建样式,或者响应您使用-D编译器args 定义的标志.但是,与C不同,代码的有条件编译部分必须在语法上完整.在使用Swift With Cocoa和Objective-C时,有一节介绍了这一点.
例如:
#if os(iOS)
let color = UIColor.redColor()
#else
let color = NSColor.redColor()
#endif
Run Code Online (Sandbox Code Playgroud)
ing*_*nti 49
我对Xcode 8的两分钱:
a)使用-D前缀的自定义标志工作正常,但......
b)使用更简单:
在Xcode 8中有一个新的部分:"Active Compilation Conditions",已有两行,用于调试和发布.
只需添加您的定义WITHOUT -D.
Jon*_*lis 43
另一个也许更简单的解决方案仍然会产生一个布尔值,你可以#if在整个代码库中传递给函数而不需要调整条件,就是将它定义DEBUG为你的项目构建目标之一Active Compilation Conditions并包含以下内容(我将其定义为全局常量):
#if DEBUG
let isDebug = true
#else
let isDebug = false
#endif
Run Code Online (Sandbox Code Playgroud)
这个概念建立在kennytm的答案之上
与kennytm进行比较时的主要优点是,这不依赖于私有或未记录的方法.
在Swift 4中:
let isDebug: Bool = {
var isDebug = false
// function with a side effect and Bool return value that we can pass into assert()
func set(debug: Bool) -> Bool {
isDebug = debug
return isDebug
}
// assert:
// "Condition is only evaluated in playgrounds and -Onone builds."
// so isDebug is never changed to true in Release builds
assert(set(debug: true))
return isDebug
}()
Run Code Online (Sandbox Code Playgroud)
与预处理器宏和kennytm的答案相比,
-D DEBUG标志即可使用它✓已记录,这意味着该功能将遵循正常的API发布/弃用模式.
✓在if/else中使用不会生成"永不执行"警告.
Vad*_*ine 22
在使用Xcode版本9.4.1,Swift 4.1创建的Swift项目中
#if DEBUG
#endif
Run Code Online (Sandbox Code Playgroud)
默认情况下,因为在预处理器宏中,DEBUG = 1已由Xcode设置.
所以你可以使用#if DEBUG"开箱即用".
顺便说一下,如何使用条件编译块一般是在Apple的书Swift编程语言4.1(编译器控件语句一节)中编写的,以及如何编写编译标志以及Swift中C宏的对应部分是用另一本Apple的书"将Swift与Cocoa和Objective C一起使用"(在预处理程序指令一节中)
希望将来Apple会为他们的书写下更详细的内容和索引.
Moj*_*ini 15
有一些处理器会接受参数,我在下面列出了它们。您可以根据需要更改参数:
#if os(macOS) /* Checks the target operating system */
#if canImport(UIKit) /* Check if a module presents */
#if swift(<5) /* Check the Swift version */
#if targetEnvironment(simulator) /* Check envrionments like Simulator or Catalyst */
#if compiler(<7) /* Check compiler version */
Run Code Online (Sandbox Code Playgroud)
此外,您可以使用任何自定义标志,如DEBUG您定义的任何其他标志
#if DEBUG
print("Debug mode")
#endif
Run Code Online (Sandbox Code Playgroud)
mid*_*n p 13
XCODE 9及以上
#if DEVELOP
//
#elseif PRODCTN
//
#else
//
#endif
Run Code Online (Sandbox Code Playgroud)
Saz*_*han 12
Moignans 在这里的回答很好。如果有帮助,这里还有另一条信息,
#if DEBUG
let a = 2
#else
let a = 3
#endif
Run Code Online (Sandbox Code Playgroud)
您可以像下面那样否定宏,
#if !RELEASE
let a = 2
#else
let a = 3
#endif
Run Code Online (Sandbox Code Playgroud)
设置完成后DEBUG=1您的GCC_PREPROCESSOR_DEFINITIONS生成设置我更喜欢使用的功能,使这个调用:
func executeInProduction(_ block: () -> Void)
{
#if !DEBUG
block()
#endif
}
Run Code Online (Sandbox Code Playgroud)
然后在这个函数中包含我想在Debug构建中省略的任何块:
executeInProduction {
Fabric.with([Crashlytics.self]) // Compiler checks this line even in Debug
}
Run Code Online (Sandbox Code Playgroud)
与以下方面相比的优势:
#if !DEBUG
Fabric.with([Crashlytics.self]) // This is not checked, may not compile in non-Debug builds
#endif
Run Code Online (Sandbox Code Playgroud)
是编译器检查我的代码的语法,所以我确信它的语法是正确的和构建.
小智 5
![在 Xcode 8 及以上版本中,转到构建设置 -> 搜索自定义标志] 1
在代码中
#if Live
print("Live")
#else
print("debug")
#endif
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
233231 次 |
| 最近记录: |