swift语言java_用Swift语言替换#ifdef
回答(15)
2 years ago
Swift編譯器不包含預(yù)處理器 . 相反,它利用編譯時(shí)屬性,構(gòu)建配置和語言功能來實(shí)現(xiàn)相同的功能 . 因此,預(yù)處理程序指令不會(huì)在Swift中導(dǎo)入 .
我已經(jīng)通過使用自定義構(gòu)建配置實(shí)現(xiàn)了我想要的目標(biāo):
轉(zhuǎn)到您的項(xiàng)目/選擇目標(biāo)/構(gòu)建設(shè)置/搜索自定義標(biāo)志
對(duì)于您選擇的目標(biāo),使用-D前綴(不帶空格)為Debug和Release設(shè)置自定義標(biāo)志
為您擁有的每個(gè)目標(biāo)執(zhí)行上述步驟
以下是檢查目標(biāo)的方法:
#if BANANA
print("We have a banana")
#elseif MELONA
print("Melona")
#else
print("Kiwi")
#endif
使用Swift 2.2測(cè)試
2 years ago
func inDebugBuilds(_ code: () -> Void) {
assert({ code(); return true }())
}
2 years ago
在許多情況下,您并不需要條件編譯;你只需要可以打開和關(guān)閉的條件行為 . 為此,您可以使用環(huán)境變量 . 這具有巨大的優(yōu)勢(shì),您實(shí)際上不必重新編譯 .
您可以在方案編輯器中設(shè)置環(huán)境變量,并輕松打開或關(guān)閉它:
您可以使用NSProcessInfo檢索環(huán)境變量:
let dic = NSProcessInfo.processInfo().environment
if dic["TRIPLE"] != nil {
// ... do secret stuff here ...
}
這是一個(gè)真實(shí)的例子 . 我的應(yīng)用程序僅在設(shè)備上運(yùn)行,因?yàn)樗褂媚M器上不存在的音樂庫 . 那么,如何在模擬器上為我不擁有的設(shè)備拍攝屏幕截圖?沒有那些屏幕截圖,我無法提交到AppStore .
我需要假數(shù)據(jù)和不同的處理方式 . 我有兩個(gè)環(huán)境變量:一個(gè)在打開時(shí)告訴應(yīng)用程序在我的設(shè)備上運(yùn)行時(shí)從真實(shí)數(shù)據(jù)生成虛假數(shù)據(jù);另一個(gè),當(dāng)打開時(shí),在模擬器上運(yùn)行時(shí)使用假數(shù)據(jù)(而不是丟失的音樂庫) . 由于Scheme編輯器中的環(huán)境變量復(fù)選框,可以輕松打開/關(guān)閉每個(gè)特殊模式 . 獎(jiǎng)金是我不能在我的App Store構(gòu)建中意外使用它們,因?yàn)闅w檔沒有環(huán)境變量 .
2 years ago
沒有Swift預(yù)處理器 . (一方面,任意代碼替換會(huì)破壞類型和內(nèi)存安全性 . )
但是,Swift確實(shí)包含構(gòu)建時(shí)配置選項(xiàng),因此您可以有條件地包含某些平臺(tái)的代碼或構(gòu)建樣式,或者響應(yīng)您使用 -D compiler args定義的標(biāo)志 . 但是,與C不同,代碼的有條件編譯部分必須在語法上完整 . 在Using Swift With Cocoa and Objective-C中有關(guān)于此的部分 .
例如:
#if os(iOS)
let color = UIColor.redColor()
#else
let color = NSColor.redColor()
#endif
2 years ago
這構(gòu)建在依賴于assert的Jon Willis's answer上,而assert僅在Debug編譯中執(zhí)行:
func Log(_ str: String) {
assert(DebugLog(str))
}
func DebugLog(_ str: String) -> Bool {
print(str)
return true
}
我的用例是用于記錄打印語句 . 以下是iPhone X上發(fā)布版本的基準(zhǔn):
let iterations = 100_000_000
let time1 = CFAbsoluteTimeGetCurrent()
for i in 0 ..< iterations {
Log ("? unarchiveArray:\(fileName) memoryTime:\(memoryTime) count:\(array.count)")
}
var time2 = CFAbsoluteTimeGetCurrent()
print ("Log: \(time2-time1)" )
打印:
Log: 0.0
看起來Swift 4完全消除了函數(shù)調(diào)用 .
2 years ago
Xcode 8出現(xiàn)了 ifdef 替換的一個(gè)重大變化,即使用 Active Compilation Conditions .
請(qǐng)參閱Xcode 8 Release note中的 Building and Linking .
新的構(gòu)建設(shè)置
新設(shè)置: SWIFT_ACTIVE_COMPILATION_CONDITIONS
“Active Compilation Conditions” is a new build setting for passing conditional compilation flags to the Swift compiler.
以前,我們必須在OTHER_SWIFT_FLAGS下聲明您的條件編譯標(biāo)志,記住在設(shè)置前加上“-D” . 例如,要使用MYFLAG值進(jìn)行有條件的編譯:
#if MYFLAG1
// stuff 1
#elseif MYFLAG2
// stuff 2
#else
// stuff 3
#endif
要添加到設(shè)置的值 -DMYFLAG
現(xiàn)在我們只需要將值MYFLAG傳遞給新設(shè)置 . 是時(shí)候移動(dòng)所有這些條件編譯值了!
2 years ago
Xcode 8及以上
在 Build settings / Swift compiler - Custom flags 中使用 Active Compilation Conditions 設(shè)置 .
這是用于將條件編譯標(biāo)志傳遞給Swift編譯器的新構(gòu)建設(shè)置 .
簡單添加這樣的標(biāo)志: ALPHA , BETA 等 .
然后用 compilation conditions 檢查它,如下所示:
#if ALPHA
//
#elseif BETA
//
#else
//
#endif
提示:您也可以使用#if!ALPHA等 .
2 years ago
在使用Xcode版本9.4.1,Swift 4.1創(chuàng)建的Swift項(xiàng)目中
#if DEBUG
#endif
默認(rèn)情況下有效,因?yàn)樵陬A(yù)處理器宏中,XB已經(jīng)設(shè)置了DEBUG = 1 .
所以你可以使用#if DEBUG“開箱即用” .
順便說一下,如何使用條件編譯塊一般是在Apple的書Swift編程語言4.1(編譯器控件語句一節(jié))中編寫的,以及如何編寫編譯標(biāo)志以及Swift中C宏的對(duì)應(yīng)部分是用另一本Apple的書“使用Swift與Cocoa和Objective C”(在預(yù)處理程序指令一節(jié)中)
希望將來Apple會(huì)為他們的書寫下更詳細(xì)的內(nèi)容和索引 .
2 years ago
在 GCC_PREPROCESSOR_DEFINITIONS Build Settings中設(shè)置 DEBUG=1 后,我更喜歡使用函數(shù)來進(jìn)行此調(diào)用:
func executeInProduction(_ block: () -> Void)
{
#if !DEBUG
block()
#endif
}
然后在這個(gè)函數(shù)中包含我想在Debug構(gòu)建中省略的任何塊:
executeInProduction {
Fabric.with([Crashlytics.self]) // Compiler checks this line even in Debug
}
相比之下的優(yōu)勢(shì)至:
#if !DEBUG
Fabric.with([Crashlytics.self]) // This is not checked, may not compile in non-Debug builds
#endif
是編譯器檢查我的代碼的語法,所以我確信它的語法是正確的和構(gòu)建 .
2 years ago
我對(duì)Xcode 8的兩分錢:
a)使用 -D 前綴的自定義標(biāo)志工作正常,但......
b)使用更簡單:
在Xcode 8中有一個(gè)新的部分:“Active Compilation Conditions”,已經(jīng)有兩行,用于調(diào)試和發(fā)布 .
只需添加您的定義WITHOUT -D .
2 years ago
從Swift 4.1開始,如果您只需要檢查代碼是使用調(diào)試版還是發(fā)布版構(gòu)建的,那么您可以使用內(nèi)置函數(shù):
_isDebugAssertConfiguration() (優(yōu)化設(shè)置為 -Onone 時(shí)為true)
_isReleaseAssertConfiguration()(當(dāng)優(yōu)化設(shè)置為-O時(shí)為true)(在Swift 3上不可用)
_isFastAssertConfiguration() (優(yōu)化設(shè)置為 -Ounchecked 時(shí)為true)
例如
func obtain() -> AbstractThing {
if _isDebugAssertConfiguration() {
return DecoratedThingWithDebugInformation(Thing())
} else {
return Thing()
}
}
與預(yù)處理器宏相比,
?您無需定義自定義 -D DEBUG 標(biāo)志即可使用它
~它實(shí)際上是根據(jù)優(yōu)化設(shè)置定義的,而不是Xcode構(gòu)建配置
?未記載,這意味著可以在任何更新中刪除該函數(shù)(但它應(yīng)該是AppStore安全的,因?yàn)閮?yōu)化器會(huì)將這些變?yōu)槌A?
?在if / else中使用將始終生成“永不執(zhí)行”警告 .
2 years ago
在代碼中
#if Live
print("Live")
#else
print("debug")
#endif
2 years ago
是的,你可以做到 .
在Swift中,您仍然可以使用"#if/#else/#endif"預(yù)處理器宏(盡管更受約束),如Apple docs . 這是一個(gè)例子:
#if DEBUG
let a = 2
#else
let a = 3
#endif
現(xiàn)在,您必須在其他位置設(shè)置"DEBUG"符號(hào) . 將其設(shè)置在"Swift Compiler - Custom Flags"部分,"Other Swift Flags"行 . 使用 -D DEBUG 條目添加DEBUG符號(hào) .
像往常一樣,您可以在Debug或Release中設(shè)置不同的值 .
我用真實(shí)的代碼測(cè)試它,它的工作原理;但它似乎并沒有在游樂場(chǎng)中得到認(rèn)可 .
你可以閱讀我原來的帖子here .
IMPORTANT NOTE: -DDEBUG=1 不起作用 . 只有 -D DEBUG 有效 . 似乎編譯器忽略了具有特定值的標(biāo)志 .
2 years ago
isDebug常量基于活動(dòng)編譯條件
另一個(gè)也許更簡單的解決方案仍然會(huì)產(chǎn)生一個(gè)布爾值,您可以將代碼庫中的 #if 條件定義為 DEBUG ,并將其定義為 DEBUG 并將其定義為全局常量 . :
#if DEBUG
let isDebug = true
#else
let isDebug = false
#endif
isDebug常量基于編譯器優(yōu)化設(shè)置
與kennytm進(jìn)行比較時(shí)的主要優(yōu)點(diǎn)是,這不依賴于私有或未記錄的方法 .
在 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
}()
與預(yù)處理器宏和kennytm的答案相比,
?您無需定義自定義 -D DEBUG 標(biāo)志即可使用它
~它實(shí)際上是根據(jù)優(yōu)化設(shè)置定義的,而不是Xcode構(gòu)建配置
? Documented ,這意味著該函數(shù)將遵循正常的API發(fā)布/棄用模式 .
?在if / else中使用將 not 生成"Will never be executed"警告 .
2 years ago
XCODE 9 AND ABOVE
#if DEVELOP
//
#elseif PRODCTN
//
#else
//
#endif
總結(jié)
以上是生活随笔為你收集整理的swift语言java_用Swift语言替换#ifdef的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 任意文件上传mysql_BigDump
- 下一篇: spark比java快吗_为什么我的Sp