2014년 6월 17일 화요일

Swift - 유용한 전처리기(Preprocessor)

전처리기(Preprocessor)란 말은 C나 C++에서 쓰이는 의미와 동일하다. 컴파일 타임 시 처리되는 특수한 구문으로 #으로 시작되는 명령어이다. 심지어 문법도 비슷하다. 하지만 심각한 차이점도 있다보니 별도로 메모를 해 두는게 좋을 것 같아서 글을 남긴다.

OS 구분하기

OS가 iOS인지 OS X인지 구분하기 위해서 아래와 같은 전처리를 이용한다.
#if os(iOS)
    // iOS용 코드
#elseif os(OSX)
    // OS X용 코드
#else
    // 이 경우는 아직은 없겠지?
#endif
앞서 이야기 한 대로 전처리기는 컴파일 되기 전에 로딩된 코드가 바뀌는 형식이기 때문에 퍼포먼스 저하 없이 OS를 구분하기 위한 코드를 넣기 위한 용도로 사용된다.

물론 빌드 때 해당 OS에 맞는 코드만 빌드가 되니 범용 프레임워크를 만드는 거라면 써서는 안되겠지만...

아키텍쳐 구분하기

사실 OS 구분하기와 다른 차이가 있을까 생각되기도 한다. 아키텍쳐가 arm과 i386 두 가지인데 이 둘은 현재는 iOS와 OS X로 명확하게 나뉘기 때문이다. 그래서 적어보자.
#if arch(arm)
    // ARM용 코드
#elseif arch(i386)
    // i386(x86, 인텔 호환)용 코드
#else
    // 모르는 아키텍쳐
#endif
대충 이런 식인데, 아키텍쳐에 맞는 최적화 과정이 필요한게 아니라면 이 전처리는 별로 쓸 일은 없을 것 같다.

변경된 전처리기

#warning 은 빌드 시 경고메시지를 출력하기 위한 용도인데 Swift에선 주석문 형태로 문법이 바뀔 예정이다. 이 말은 현재 Xcode 6 Beta 1 에선 동작하지 않고 다음 Xcode 베타 릴리즈 때 추가될 예정이라고 한다.
// Objective-C
#warning This feature not supported in this platform.

// Swift
// WARNING: This feature not supported in this platform.
#pragma mark 의 경우도 Swift에선 주석문으로 변경될 예정이다. 역시 다음 Xcode 6 베타부터 지원될 예정이다.
// Objective-C
#pragma mark -
#pragma mark Initializer
// or
#pragma mark - Initializer

// Swift
// MARK: Initializer
사족이지만, 아무리 베타라도 좀 너무한다는 생각이 든다. 미완성으로 내놓다니 ㅠㅠ

문제

스위프트에서는 #define#ifdef 전처리기를 지원하지 않는다. 심지어 #if defined 같은 구문도 Unexpected expression 오류가 발생한다. 안타깝지만 컴파일 타임 때 이용 가능한 전처리 매크로 기능은 더 이상은 사용 할 수 없을지도 모른다.

참고로 애플의 공식 문서에서도 전처리 매크로 말고 let 으로 상수 만들어서 쓰라고 한다. 쳇...

버그

#if ~ #endif 구문에 버그가 있었다. 정확히 이야기 하자면 Xcode 6 Beta 에서 발생하는 문제라고 생각된다.

파일의 끝이 #endif 로 끝나면 Unexpected expression 오류가 발생한다. 아래 스크린샷이 그 예이다.


솔직히 말도 안되는 오류인데 일단 그 아래 라인에 뭔가를 추가하면 에러가 사라진다.


위에서는 그냥 주석 한줄 추가해서 에러를 회피했다.

물론 이 버그는 수정되겠지? -_-

댓글 없음 :