V C / C ++ / Objective-C môžete definovať makro pomocou preprocesorov kompilátora. Navyše môžete zahrnúť / vylúčiť niektoré časti kódu pomocou preprocesorov kompilátora.
#ifdef DEBUG
// Debug-only code
#endif
Existuje podobné riešenie v Swifte?
odpovede:
857 za odpoveď č. 1Áno, môžete to urobiť.
V Swifte môžete stále používať preprocesorové makra „# if / # else / # endif“ (aj keď sú viac obmedzené) podľa Apple docs, Tu je príklad:
#if DEBUG
let a = 2
#else
let a = 3
#endif
Teraz však musíte nastaviť symbol „DEBUG“ inde. Nastavte ho v časti „Kompilátor Swift - Vlastné vlajky“, riadok „Ostatné vlajky Swift“. Symbol DEBUG pridáte pomocou -D DEBUG
entry.
Ako obvykle môžete nastaviť inú hodnotu pri ladení alebo pri vydaní.
Testoval som to v reálnom kóde a funguje to; nezdá sa, že by to bolo rozpoznané na detskom ihrisku.
Môžete si prečítať môj pôvodný príspevok tu.
DÔLEŽITÁ POZNÁMKA: -DDEBUG=1
nefunguje. Iba -D DEBUG
Tvorba. Zdá sa, že kompilátor ignoruje príznak s konkrétnou hodnotou.
286 pre odpoveď č. 2
Ako sa uvádza v Apple Docs
Kompilátor Swift neobsahuje apreprocesor. Namiesto toho využíva atribúty času kompilácie, zostavenie konfigurácií a jazykové funkcie na dosiahnutie rovnakej funkcie. Z tohto dôvodu sa direktívy preprocesora do aplikácie Swift neimportujú.
Podarilo sa mi dosiahnuť to, čo som chcel, pomocou vlastných konfigurácií zostavy:
- Prejdite do svojho projektu / vyberte cieľ / Nastavenia zostavy / vyhľadajte Vlastné vlajky
- Pre svoj zvolený cieľ nastavte svoj vlastný príznak pomocou prefixu -D (bez medzier), pre Debug aj Release
- Vyššie uvedené kroky urobte pre každý cieľ, ktorý máte
Takto skontrolujete cieľ:
#if BANANA
print("We have a banana")
#elseif MELONA
print("Melona")
#else
print("Kiwi")
#endif
Testované pomocou Swift 2.2
145 za odpoveď č. 3
V mnohých situáciách naozaj nepotrebujete podmienečné podmienky zostavenie; len treba podmienene správanie že môžete zapnúť a vypnúť. Na to môžete použiť premennú prostredia. To má obrovskú výhodu, že v skutočnosti nemusíte prekompilovať.
Premennú prostredia môžete nastaviť a ľahko zapnúť alebo vypnúť v editore schém:
Premennú prostredia môžete načítať pomocou NSProcessInfo:
let dic = NSProcessInfo.processInfo().environment
if dic["TRIPLE"] != nil {
// ... do secret stuff here ...
}
Tu je príklad zo skutočného života.Moja aplikácia je spustená iba na zariadení, pretože využíva hudobnú knižnicu, ktorá v Simulátore neexistuje. Ako potom na Simulátore snímať obrazovky na zariadeniach, ktoré nevlastním? Bez týchto snímok obrazovky nemôžem odoslať do AppStore.
potrebujem falošné údaje a a iný spôsob jeho spracovania. Mám dve premenné prostredia:ten, ktorý po zapnutí povie aplikácii, aby generovala falošné údaje zo skutočných údajov, keď je spustená v mojom zariadení; druhá, ktorá po zapnutí používa falošné údaje (nie chýbajúcu hudobnú knižnicu), keď je spustená na simulátore. Zapnutie a vypnutie každého z týchto špeciálnych režimov je jednoduché vďaka začiarkavacím políčkam premenných prostredia v editore schém. A bonusom je, že ich „nemôžem náhodne použiť v mojej zostave App Store, pretože archivácia nemá žiadne premenné prostredia.
119 pre odpoveď č. 4
Zásadná zmena ifdef
náhrada prišla s Xcode 8. teda použitie Podmienky aktívneho zostavenia.
Odkazujú na Budovanie a prepájanie v Xcode 8 Poznámka k vydaniu.
Nové nastavenie zostavy
Nové nastavenie: SWIFT_ACTIVE_COMPILATION_CONDITIONS
“Active Compilation Conditions” is a new build setting for passing conditional compilation flags to the Swift compiler.
Predtým sme museli deklarovať vaše príznaky podmienenej kompilácie pod OTHER_SWIFT_FLAGS, pričom sme nezabudli pred nastavenie pridať „-D“. Napríklad na podmienenú kompiláciu s hodnotou MYFLAG:
#if MYFLAG1
// stuff 1
#elseif MYFLAG2
// stuff 2
#else
// stuff 3
#endif
Hodnota, ktorá sa má pridať k nastaveniu -DMYFLAG
Teraz už stačí iba odovzdať hodnotu MYFLAG do nového nastavenia. Je čas presunúť všetky tieto podmienené hodnoty kompilácie!
Ďalšie funkcie Swift Build Settings v Xcode 8 nájdete na nasledujúcom odkaze: http://www.miqu.me/blog/2016/07/31/xcode-8-new-build-settings-and-analyzer-improvements/
73 pre odpoveď № 5
Od verzie Swift 4.1, ak potrebujete iba skontrolovať, či je kód zostavený s konfiguráciou ladenia alebo vydania, môžete použiť vstavané funkcie:
_isDebugAssertConfiguration()
(pravda, keď je optimalizácia nastavená na-Onone
)(nie je k dispozícii pre Swift 3+)_isReleaseAssertConfiguration()
(pravda, keď je optimalizácia nastavená na-O
)_isFastAssertConfiguration()
(pravda, keď je optimalizácia nastavená na-Ounchecked
)
napr.
func obtain() -> AbstractThing {
if _isDebugAssertConfiguration() {
return DecoratedThingWithDebugInformation(Thing())
} else {
return Thing()
}
}
V porovnaní s makrami predprocesora
- ✓ Nemusíte definovať zvyk
-D DEBUG
príznak použiť - ~ Je to vlastne definované z hľadiska nastavení optimalizácie, nie konfigurácie zostavenia Xcode
✗ Nedokumentované, čo znamená, že túto funkciu je možné odstrániť v ktorejkoľvek aktualizácii (mala by však byť bezpečná v obchode AppStore, pretože optimalizátor z nich urobí konštanty).
- tieto raz odstránený, ale vrátená verejnosti na nedostatok
@testable
atribút, osud neistý pre budúci Swift.
- tieto raz odstránený, ale vrátená verejnosti na nedostatok
✗ Použitie príkazu if / else vždy vygeneruje varovanie „Nikdy sa nespustí“.
72 pre odpoveď č. 6
použitie Podmienky aktívneho zostavenia nastavenie v Zostavenie nastavení / kompilátor Swift - vlastné vlajky.
- Toto je nové nastavenie zostavenia na odovzdávanie príznakov podmienenej kompilácie kompilátoru Swift.
- Jednoduché pridanie príznakov, ako je tento:
ALPHA
,BETA
atď.
Potom to skontrolujte pomocou podmienky kompilácie ako toto:
#if ALPHA
//
#elseif BETA
//
#else
//
#endif
Tip: Môžete tiež použiť
#if !ALPHA
atď.
69 pre odpoveď č. 7
Neexistuje preprocesor Swift. (Za prvé, ľubovoľná zámena kódu prerušuje bezpečnosť typu a pamäte.)
Swift však obsahuje možnosti konfigurácie v čase zostavenia, takže môžete podmienečne zahrnúť kód pre určité platformy alebo štýly stavania alebo v reakcii na príznaky, ktoré definujete pomocou -D
kompilátor args. Na rozdiel od C však musí byť podmienene skompilovaná časť vášho kódu syntakticky úplná. O tejto téme je časť Používanie Swift s kakaom a Objective-C.
Napríklad:
#if os(iOS)
let color = UIColor.redColor()
#else
let color = NSColor.redColor()
#endif
39 pre odpoveď č. 8
Moje dva centy za Xcode 8:
a) Vlastný príznak pomocou -D
predpona funguje dobre, ale ...
b) Jednoduchšie použitie:
V Xcode 8 sa nachádza nová sekcia: „Podmienky aktívnej kompilácie“, už s dvoma riadkami, na ladenie a vydanie.
Jednoducho zadajte svoju definíciu BEZ -D
.
24 pre odpoveď č. 9
Konštanta isDebug je založená na podmienkach aktívnej kompilácie
Ďalšie, možno jednoduchšie riešenie, ktoré má stále za následok boolean, ktorý môžete odovzdať do funkcií bez korenia #if
podmienkami v celej vašej kódovej základni je definovať DEBUG
ako jeden z cieľových cieľov projektu Active Compilation Conditions
a zahrnúť nasledujúce (definujem to ako globálnu konštantu):
#if DEBUG
let isDebug = true
#else
let isDebug = false
#endif
Konštanta isDebug je založená na nastaveniach optimalizácie kompilátora
Tento koncept nadväzuje na kennymova odpoveď
Hlavnou výhodou v porovnaní s kennym je, že sa nespolieha na súkromné alebo neregistrované metódy.
v 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
}()
V porovnaní s makrami preprocesora a kennymova odpoveď,
- ✓ Nemusíte definovať zvyk
-D DEBUG
príznak použiť - ~ Je to vlastne definované z hľadiska nastavení optimalizácie, nie konfigurácie zostavenia Xcode
✓ zdokumentované, čo znamená, že funkcia bude postupovať podľa bežných vzorov uvoľňovania / ukončovania podpory API.
✓ Použitie v if / else bude nie vygenerovať varovanie „Nikdy sa nevykoná“.
2 pre odpoveď č. 10
Po nastavení DEBUG=1
vo vašom GCC_PREPROCESSOR_DEFINITIONS
Vytváranie nastavení Dávam prednosť použitiu funkcie na uskutočnenie týchto hovorov:
func executeInProduction(_ block: () -> Void)
{
#if !DEBUG
block()
#endif
}
A potom stačí vložiť do tejto funkcie akýkoľvek blok, ktorý chcem vynechať v zostavách Debug:
executeInProduction {
Fabric.with([Crashlytics.self]) // Compiler checks this line even in Debug
}
Výhoda v porovnaní s:
#if !DEBUG
Fabric.with([Crashlytics.self]) // This is not checked, may not compile in non-Debug builds
#endif
Je to tak, že kompilátor kontroluje syntax môjho kódu, takže som si istý, že jeho syntax je správna a zostavená.
1 pre odpoveď č. 11
To stavia na Jon Willis odpoveď, ktorá sa spolieha na tvrdenie, ktoré sa vykoná iba v kompiláciách Debug:
func Log(_ str: String) {
assert(DebugLog(str))
}
func DebugLog(_ str: String) -> Bool {
print(str)
return true
}
Môj prípad použitia je na zaznamenávanie tlačových výpisov. Tu je referenčná hodnota pre verziu Release na 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)" )
tlačí:
Log: 0.0
Vyzerá to, že Swift 4 úplne vylučuje volanie funkcie.
0 pre odpoveď č. 12
! [V Xcode 8 a vyššie prejdite na nastavenie zostavenia -> vyhľadajte vlastné vlajky ]1
V kóde
#if Live
print("Live")
#else
print("debug")
#endif