[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에서 가져 오지 않습니다.

사용자 정의 빌드 구성을 사용하여 원하는 것을 달성했습니다.

  1. 프로젝트로 이동 / 대상 선택 / 빌드 설정 / 사용자 정의 플래그 검색
  2. 선택한 대상의 경우 디버그 및 릴리스 모두에 -D 접두사 (공백없이)를 사용하여 사용자 정의 플래그를 설정하십시오.
  3. 가지고있는 모든 대상에 대해 위의 단계를 수행하십시오.

대상을 확인하는 방법은 다음과 같습니다.

#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 Conditionsis 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)
  • _isReleaseAssertConfiguration()(최적화가로 설정된 경우 true -O) (Swift 3+에서는 사용할 수 없음)
  • _isFastAssertConfiguration()(최적화가로 설정된 경우 true -Ounchecked)

예 :

func obtain() -> AbstractThing {
    if _isDebugAssertConfiguration() {
        return DecoratedThingWithDebugInformation(Thing())
    } else {
        return Thing()
    }
}

전 처리기 매크로와 비교할 때

  • -D DEBUG사용하기 위해 커스텀 플래그를 정의 할 필요가 없습니다.
  • ~ 실제로 Xcode 빌드 구성이 아닌 최적화 설정 측면에서 정의됩니다.
  • document 문서화되지 않음-모든 업데이트에서 함수를 제거 할 수 있음을 의미합니다 (그러나 옵티마이 저가이를 상수로 변환하므로 AppStore 안전해야 함).

  • 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