在 C 系語言中,可以使用 #if 或者 #ifdef 之類的編譯條件分支來控制哪些代碼需要編譯,而哪些代碼不需要。Swift 中沒有宏定義的概念,因此我們不能使用 #ifdef 的方法來檢查某個(gè)符號(hào)是否經(jīng)過宏定義。但是為了控制編譯流程和內(nèi)容,Swift 還是為我們提供了幾種簡(jiǎn)單的機(jī)制來根據(jù)需求定制編譯內(nèi)容的。
首先是 #if 這一套編譯標(biāo)記還是存在的,使用的語法也和原來沒有區(qū)別:
#if <condition>
#elseif <condition>
#else
#endif
當(dāng)然,#elseif 和 #else 是可選的。
但是這幾個(gè)表達(dá)式里的 condition 并不是任意的。Swift 內(nèi)建了幾種平臺(tái)和架構(gòu)的組合,來幫助我們?yōu)椴煌钠脚_(tái)編譯不同的代碼,具體地:
| 方法 | 可選參數(shù) |
|---|---|
| 方法 | 可選參數(shù) |
| os() | macOS, iOS, tvOS, watchOS, Linux |
| arch() | x86_64, arm, arm64, i386 |
| swift() | >= 某個(gè)版本 |
注意這些方法和參數(shù)都是大小寫敏感的。舉個(gè)例子,如果我們統(tǒng)一我們?cè)?iOS 平臺(tái)和 Mac 平臺(tái)的關(guān)于顏色的 API 的話,一種可能的方法就是配合 typealias 進(jìn)行條件編譯:
#if os(macOS)
typealias Color = NSColor
#else
typealias Color = UIColor
#endif
雖然 Swift 現(xiàn)在只能在上面列表中列出的平臺(tái)上運(yùn)行,但是 os() 的可選用參數(shù)還包括 "FreeBSD","Windows" 和 "Android"。也許我們?cè)诓痪玫膶砭湍軌蛟谶@些平臺(tái)上看到 Swift 的身影。
另外對(duì)于 arch() 的參數(shù)需要說明的是 arm 和 arm64 兩項(xiàng)分別對(duì)應(yīng) 32 位 CPU 和 64 位 CPU 的真機(jī)情況,而對(duì)于模擬器,相應(yīng)地 32 位設(shè)備的模擬器和 64 位設(shè)備的模擬器所對(duì)應(yīng)的分別是 i386 和 x86_64,它們也是需要分開對(duì)待的。
另一種方式是對(duì)自定義的符號(hào)進(jìn)行條件編譯,比如我們需要使用同一個(gè) target 完成同一個(gè) app 的收費(fèi)版和免費(fèi)版兩個(gè)版本,并且希望在點(diǎn)擊某個(gè)按鈕時(shí)收費(fèi)版本執(zhí)行功能,而免費(fèi)版本彈出提示的話,可以使用類似下面的方法:
@IBAction func someButtonPressed(sender: AnyObject!) {
#if FREE_VERSION
// 彈出購買提示,導(dǎo)航至商店等
#else
// 實(shí)際功能
#endif
}
在這里我們用 FREE_VERSION 這個(gè)編譯符號(hào)來代表免費(fèi)版本。為了使之有效,我們需要在項(xiàng)目的編譯選項(xiàng)中進(jìn)行設(shè)置,在項(xiàng)目的 Build Settings 中,找到 Swift Compiler - Custom Flags,并在其中的 Other Swift Flags 加上 -D FREE_VERSION 就可以了。