[swift] Swift 언어에서 #ifdef 교체
C / C ++ / Objective C에서는 컴파일러 전처리기를 사용하여 매크로를 정의 할 수 있습니다. 또한 컴파일러 전처리기를 사용하여 일부 코드 부분을 포함 / 제외 할 수 있습니다.
#ifdef DEBUG
// Debug-only code
#endif
Swift에도 비슷한 솔루션이 있습니까?
답변
그렇습니다 당신은 그것을 할 수 있습니다.
Swift에서는 Apple 문서에 따라 여전히 “# if / # else / # endif”전 처리기 매크로를 사용할 수 있습니다 (더 제한적 임) . 예를 들면 다음과 같습니다.
#if DEBUG
let a = 2
#else
let a = 3
#endif
이제 “DEBUG”기호를 다른 곳에 설정해야합니다. “Swift Compiler-Custom Flags”섹션, “Other Swift Flags”라인에서 설정하십시오. -D DEBUG
항목 과 함께 DEBUG 기호를 추가합니다 .
일반적으로 디버그 또는 릴리스시 다른 값을 설정할 수 있습니다.
실제 코드로 테스트했으며 작동합니다. 운동장에서는 인식되지 않는 것 같습니다.
내 원래 게시물을 여기에서 읽을 수 있습니다 .
중요 사항 : -DDEBUG=1
작동하지 않습니다. 만 -D DEBUG
작동합니다. 컴파일러가 특정 값을 가진 플래그를 무시하는 것 같습니다.
답변
Apple Docs에 명시된 바와 같이
Swift 컴파일러에는 전처리 기가 포함되어 있지 않습니다. 대신 컴파일 타임 속성, 빌드 구성 및 언어 기능을 활용하여 동일한 기능을 수행합니다. 이러한 이유로 전 처리기 지시문은 Swift에서 가져 오지 않습니다.
사용자 정의 빌드 구성을 사용하여 원하는 것을 달성했습니다.
- 프로젝트로 이동 / 대상 선택 / 빌드 설정 / 사용자 정의 플래그 검색
- 선택한 대상의 경우 디버그 및 릴리스 모두에 -D 접두사 (공백없이)를 사용하여 사용자 정의 플래그를 설정하십시오.
- 가지고있는 모든 대상에 대해 위의 단계를 수행하십시오.
대상을 확인하는 방법은 다음과 같습니다.
#if BANANA
print("We have a banana")
#elseif MELONA
print("Melona")
#else
print("Kiwi")
#endif
Swift 2.2를 사용하여 테스트
답변
많은 상황에서 실제로 조건부 컴파일 이 필요하지 않습니다 . 켜고 끌 수있는 조건부 동작 만 있으면 됩니다. 이를 위해 환경 변수를 사용할 수 있습니다. 이것은 실제로 다시 컴파일 할 필요가 없다는 큰 이점이 있습니다.
체계 편집기에서 환경 변수를 설정하고 쉽게 켜거나 끌 수 있습니다.
NSProcessInfo를 사용하여 환경 변수를 검색 할 수 있습니다.
let dic = NSProcessInfo.processInfo().environment
if dic["TRIPLE"] != nil {
// ... do secret stuff here ...
}
실제 예는 다음과 같습니다. 내 앱은 시뮬레이터에없는 음악 라이브러리를 사용하기 때문에 기기에서만 실행됩니다. 그렇다면 내가 소유하지 않은 장치의 시뮬레이터에서 스크린 샷을 찍는 방법은 무엇입니까? 스크린 샷이 없으면 AppStore에 제출할 수 없습니다.
가짜 데이터 와 다른 처리 방법이 필요 합니다 . 두 가지 환경 변수가 있습니다. 하나는 켜면 앱이 기기에서 실행되는 동안 실제 데이터에서 가짜 데이터를 생성하도록 지시합니다. 다른 하나는 스위치를 켤 때 시뮬레이터에서 실행되는 동안 누락 된 음악 라이브러리가 아닌 가짜 데이터를 사용합니다. Scheme 편집기의 환경 변수 체크 박스 덕분에 각 특수 모드를 쉽게 켜고 끌 수 있습니다. 그리고 아카이빙에는 환경 변수가 없기 때문에 실수로 App Store 빌드에서 사용할 수 없다는 것이 보너스입니다.
답변
의 주요 변화 ifdef
교체의 엑스 코드 (8) 즉, 사용 내놓았다 액티브 컴파일 조건 .
Xcode 8 릴리스 노트의 빌드 및 링크 를 참조하십시오 .
새로운 빌드 설정
새로운 설정 : 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 값만 새 설정에 전달하면됩니다. 모든 조건부 컴파일 값을 이동할 시간입니다!
Xcode 8의 Swift Build Settings 기능에 대한 자세한 내용은 아래 링크를 참조하십시오
.
답변
Swift 4.1부터는 디버그 또는 릴리스 구성으로 코드를 빌드했는지 여부 만 확인하면 내장 기능을 사용할 수 있습니다.
_isDebugAssertConfiguration()
(최적화가로 설정된 경우 true-Onone
)(Swift 3+에서는 사용할 수 없음)_isReleaseAssertConfiguration()
(최적화가로 설정된 경우 true-O
)_isFastAssertConfiguration()
(최적화가로 설정된 경우 true-Ounchecked
)
예 :
func obtain() -> AbstractThing {
if _isDebugAssertConfiguration() {
return DecoratedThingWithDebugInformation(Thing())
} else {
return Thing()
}
}
전 처리기 매크로와 비교할 때
- ✓
-D DEBUG
사용하기 위해 커스텀 플래그를 정의 할 필요가 없습니다. - ~ 실제로 Xcode 빌드 구성이 아닌 최적화 설정 측면에서 정의됩니다.
-
document 문서화되지 않음-모든 업데이트에서 함수를 제거 할 수 있음을 의미합니다 (그러나 옵티마이 저가이를 상수로 변환하므로 AppStore 안전해야 함).
- 이것들은 한때 제거 되었지만, 속성의 부족으로 다시 대중에게 돌아 왔으며
@testable
, 미래의 스위프트에서는 운명이 불확실했습니다.
- 이것들은 한때 제거 되었지만, 속성의 부족으로 다시 대중에게 돌아 왔으며
-
if if / else를 사용하면 항상 “실행되지 않습니다”경고가 발생합니다.
답변
Xcode 8 이상
빌드 설정 / Swift 컴파일러-사용자 정의 플래그 에서 활성 컴파일 조건 설정을 사용하십시오 .
- 조건부 컴파일 플래그를 Swift 컴파일러에 전달하기위한 새로운 빌드 설정입니다.
- 이런 간단한 추가 플래그 :
ALPHA
,BETA
등
그런 다음 다음 과 같은 컴파일 조건으로 확인하십시오 .
#if ALPHA
//
#elseif BETA
//
#else
//
#endif
팁 :
#if !ALPHA
등 을 사용할 수도 있습니다 .
답변
스위프트 전처리 기가 없습니다. (무엇이든 임의의 코드 대체는 유형 및 메모리 안전성을 손상시킵니다.)
Swift에는 빌드 타임 구성 옵션이 포함되어 있으므로 특정 플랫폼 또는 빌드 스타일에 대한 코드를 조건부로 포함하거나 -D
컴파일러 인수로 정의한 플래그에 응답 할 수 있습니다 . 그러나 C와 달리 조건부로 컴파일 된 코드 섹션은 구문 상 완전해야합니다. Cocoa 및 Objective-C와 함께 Swift 사용에 이에 대한 섹션이 있습니다.
예를 들면 다음과 같습니다.
#if os(iOS)
let color = UIColor.redColor()
#else
let color = NSColor.redColor()
#endif