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