제1장 Objective-C 숙지-제4조: 유형 상수를 많이 사용하고 #define 예처리 명령을 적게 사용한다.

4265 단어
코드를 작성할 때 변수를 자주 정의해야 한다.예를 들면 다음과 같습니다.
#define ANIMATION_DURATION 0.3

상기 예처리 명령은 소스 코드의 ANIMATION 을DURATION 문자열을 0.3으로 대체합니다.이것은 아마도 네가 원하는 효과일 것이다. 그러나 이렇게 정의된 상수는 유형 정보가 없다.'지속' (duration) 이라는 단어는 보아하니 시간과 관련이 있을 것 같지만 코드에는 명확하게 지적되지 않았다.또한 사전 처리 프로세스는 모든 ANIMATION을DURATION은 일률적으로 0.3으로 바뀐다. 그러면 이 지령이 어떤 헤더 파일에 성명된다고 가정하면 이 헤더 파일을 도입한 모든 코드는ANIMATIONDRRATION은 모두 대체됩니다.이 문제를 해결하려면 컴파일러의 일부 특성을 이용해야 한다.예처리 명령으로 상수를 정의하는 것보다 더 좋은 방법이 있다.예를 들어, 다음 행 코드는 NSTimeInterval 유형의 상수를 정의합니다.
static const NSTimeInterval kAnimationDuration = 0.3;

이 방식으로 정의된 상수는 유형 정보를 포함하는데, 그 장점은 상수의 의미를 명확하게 설명하는 것이다.이를 통해 알 수 있듯이 이 상수 유형은 NSTimeInterval로 개발 문서를 작성하는 데 도움이 된다.만약 많은 상수를 정의하려고 한다면, 이런 방식은 나중에 코드를 읽는 사람들로 하여금 그 의도를 더욱 쉽게 이해하게 할 수 있다.상수 명칭도 주의해야 한다.흔히 사용하는 명명법은 상수가 특정한'컴파일 단원'(translation unit, 즉'실현 파일',implementation file)에 국한되면 앞에 자모 k를 붙이는 것이다.만약 상수가 클래스 밖에서 볼 수 있다면, 보통 클래스 이름을 접두사로 한다.상수의 위치를 정의하는 것이 중요하다.우리는 항상 헤더 파일에 예처리 명령을 성명하는 것을 좋아한다. 이렇게 하는 것은 정말 엉망이다. 상수 이름이 서로 충돌할 수 있을 때 더욱 그렇다.예를 들어, ANIMATIONDURATION이라는 상수명은 헤더 파일에 사용해서는 안 된다. 왜냐하면 이 헤더 파일을 도입한 다른 모든 파일에 이 이름이 나타나기 때문이다.사실 static const로 정의된 상수조차도 헤더 파일에 나타나지 말았어야 했다.Objective-C에는 이름공간(namespace)이라는 개념이 없기 때문에 그렇게 하는 것은 kAnimationDuration이라는 전역 변수를 성명하는 것과 같다.이 이름은 EOCViewClassAnimationDuration으로 변경할 수 있는 클래스를 표시하기 위해 접두사를 붙여야 합니다.어떤 상수를 공개하지 않으려면, 그 상수를 사용하는 실행 파일에 정의해야 한다.예를 들어 UIKit 프레임워크를 사용하는 iOS 응용 프로그램을 개발하려면 UIView 하위 클래스에 애니메이션 재생 시간을 나타내는 상수가 포함되어 있으면 이렇게 쓸 수 있다.
//EOCAnimatedView.h
#import 

@interface EOCAnimatedView : UIView
- (void)animate;
@end

//EOCAnimatedView.m
#import "EOCAnimatedView.h"

static const NSTimeInterval kAnimationDuration = 0.3;

@implementation EOCAnimatedView
- (void)animate {
  [UIView animateWithDuration:kAnimationDuration
                        animations:^(){
                          //Perform animations
      }];
}
@end

변수는 반드시 static와const로 동시에 성명해야 한다.const 수식자에 의해 설명된 변수를 수정하려고 하면 컴파일러가 오류를 보고합니다.이 예에서 우리는 애니메이션이 재생되는 시간이 정해져 있기 때문에 수정해서는 안 된다.static 수식자는 이 변수가 이 변수를 정의하는 컴파일러 단원에서만 볼 수 있음을 의미한다.컴파일러가 컴파일러 단원을 받을 때마다 '대상 파일' (object file) 을 출력합니다.Objective-C의 언어 환경에서'컴파일 단원'이라는 단어는 일반적으로 모든 종류의 실현 파일(.m을 접미사로 함)을 가리킨다.따라서 상기 범례 코드에 명시된 kAnimationDuration 변수는 그 역할 영역은 EOCAnimatedView에만 한정된다.m 생성된 대상 파일에서이 변수를 선언할 때 static을 추가하지 않으면 컴파일러가 외부 기호(external symbol)를 생성합니다.이 때 다른 컴파일러 단원에서도 같은 이름의 변수를 설명하면 컴파일러가 오류 메시지를 던집니다.
duplicate symbol _kAnimationDuration in:
EOCAnimatedView.o
EOCOtherView.o

실제로 하나의 변수가static이고 const라고 성명되면 컴파일러는 기호를 만들지 않고 #define 예처리 명령처럼 모든 변수를 상수로 바꿉니다.그러나 이런 식으로 정의된 상수에는 유형 정보가 있다는 것을 명심해야 한다.어떤 상량을 대외적으로 공개해야 할 때가 있다.예를 들어, 당신은 다른 사람에게 알리기 위해 클래스 코드에서 NSNotificationCenter를 호출해야 할 수도 있습니다.하나의 대상으로 통지를 발송하여 다른 통지를 받고 싶은 대상을 이 대상에게 등록시키면 이 기능을 실현할 수 있다.알림을 보낼 때, 이 알림의 이름을 문자열로 표시해야 하며, 이 이름은 외부에서 볼 수 있는 상수 변수 (constant variable) 로 표시할 수 있습니다.이렇게 하면 등록자는 실제 문자열 값을 알 필요가 없고, 상치 변수로 자신이 받고 싶은 알림을 등록하면 된다.이러한 상수는 해당 상수를 정의하는 컴파일러 셀 외부에서 사용할 수 있도록 글로벌 기호표 (global symbol table) 에 두어야 합니다.따라서 이전 예제에서 설명한 static const와 정의 방식이 다릅니다.다음과 같이 정의해야 합니다.
//In the header file
extern NSString *const EOCStringConstant;

//In the implementation file
NSString *const EOCStringConstant = @"VALUE";

이 상수는 헤더 파일에서 '성명' 을 하고 파일의 '정의' 를 실현합니다.상수 형식의 const 수식자 위치를 주의하십시오.상수 정의는 오른쪽에서 왼쪽으로 해석해야 하기 때문에 이 예에서 EOCStringConstant는'상수이고 이 상수는 지침으로 NSString 대상을 가리킨다'는 것이다.이것은 요구 사항과 일치합니다. 우리는 이 포인터의 상수를 다른 NSString 대상을 가리키도록 바꾸는 것을 원하지 않습니다.컴파일러는 헤더 파일의 extern 키워드를 보면 이 헤더 파일을 도입한 코드에서 이 상수를 처리하는 방법을 알 수 있습니다.이 키워드는 글로벌 기호 테이블에 EOCStringConstant이라는 기호가 있음을 컴파일러에게 알려 주는 것입니다.즉, 컴파일러는 코드를 이 상수로 사용할 수 있도록 정의를 볼 필요가 없다.바이너리 파일로 연결된 후에 이 상수를 찾을 수 있다는 것을 알기 때문이다.이런 상수는 반드시 정의해야 하며, 단지 한 번만 정의할 수 있다.보통 이 상수를 설명하는 헤더 파일과 관련된 실행 파일에 정의됩니다.파일에서 대상 파일을 생성할 때 컴파일러는 '데이터 세그먼트' (data section) 에서 문자열에 저장 공간을 분배합니다.링크는 이 대상 파일을 다른 대상 파일과 연결하여 최종 바이너리 파일을 생성합니다.EOCStringConstant이라는 전역 기호를 사용하는 곳이라면 링크는 그것을 해석할 수 있다.기호는 전역 기호표에 넣어야 하기 때문에 상수를 명명할 때 조심해야 한다.
한 마디로 하면 예처리 명령을 사용하여 상수를 정의하지 말고 컴파일러를 통해 상수가 정확한지 확인해야 한다. 예를 들어 파일에서static const로 상수를 설명할 수도 있고 전체 상수를 설명할 수도 있다.

좋은 웹페이지 즐겨찾기