[Effective Objective-C] #3 메서드보다는 같은 일을 하는 리터럴 문법을 사용하라
출처 : Effective Objective-C
-
NSString, NSNumber, NSArray, NSDictionary 인스턴스 모두 리터럴 문법을 지원한다.
-
리터럴 문법을 사용하면 소스 코드 크기가 줄고 코드가 읽기 쉬워진다.
리터럴 숫자
-
정수, 실수, 불린 값을 Objective-C 로 감쌀(wrapping) 필요가 있다.
이는 숫자 타입을 다룰 수 있는 NSNumber 클래스를 이용해 할 수 있다.
-
리터럴을 쓰지 않으면 다음과 같이 생성한다.
NSNumber *number = [NSNumber numberWithInt:1];
그러나 리터럴을 사용하면 이렇게 간단하다.
NSNumber *number = @1;
-
리터럴 문법은 표현식 ( expression ) 에도 작동한다.
NSNumber *number = @(x + y);
리터럴 배열
-
NSArray *animals = [NSArray arrayWithObjects:@“cat”, @“dog”, @“mouse”, @“badger”, nil];
=>
NSArray *animals = @[@“cat”, @“dog”, @“mouse”, @“badger” ];
-
리터럴 문법으로 배열을 생성할 때 주의해야 할 점이 있다.
만약 생성하려는 객체 중 단 하나라도 nil 이면 예외를 던진다.
리터럴 문법은 배열을 생성하고 대괄호 안에 있는 모든 객체를 배열에 추가해주는 간편 문법(syntactic sugar)이기 때문이다.
-
arrayWithObjects: 는 메서드의 내부 구현이 nil 인 인자 이전의 인자들만 받아들여 array 를 생성하게 되어 있다.
이 미묘한 차이 때문에 리터럴이 좀 더 안전하다.
기대했던 인자보다 적은 인자를 가진 채 배열이 생성되는 것보다 정당한 앱 크래시의 원인이 되는 예외가 던져지는 것이 더 낫기 때문이다.
cf)
syntactic sugar : 프로그래밍 언어에서 특정 문법을 좀 더 쉽게 읽을 수 있고 표현할 수 있게 하는 대체 문법
-
NSString *dog = [animals objectAtIndex:1];
=>
NSString *dog = animals[1];
이 방식도 리터럴의 한 종류인데, 첨자(subscripting)이라고 부른다.
리터럴 사전
-
NSDictionary *personData = [NSDictionary dictionaryWithObjectsAndKeys:@“Matt”, @“firstName”, “@Galloway”, @“lastName”, [NSNumber numberWithInt:28], @“age”, nil ];
=>
NSDictionary *personData = @{@“firatName” : @“Matt”, @“lastName” : @“Galloway”, @“age” : @28 };
-
dictionaryWithObject 는 사람들이 일반적으로 생각하는 키-값 쌍이 아니라, 값-키 순으로 입력해야 하기 때문에 개념적으로 더 어렵다.
리터럴은 그런 문제를 해결해준다. ( 키-값 쌍으로 표시 )
-
배열과 같이 사전 리터럴도 만일 값들 중 하나라도 nil 이면 예외를 던진다.
같은 이유로 이는 좋은 것이다.
dictionaryWithObjectsAndKeys: 메서드는 nil 이전의 값으로만 사전을 생성해서 의도치 않게 값을 읽어버리지만 사전 리터럴은 예외를 던지기 때문이다.
-
리터럴 문법으로 값에 접근도 가능하다.
NSString *lastName = [personData objectForKey:@“lastName”];
=>
NSString *lastName = personData[@“lastName”];
제한
-
리터럴 문법은 사소한 제한이 있다.
바로 생성된 객체의 클래스는 반드시 Foundation 프레임워크의 클래스여야 한다는 것이다. ( 문자열 제외 )
생성되기로 한 클래스 대신에 자신이 만든 커스텀 하위 클래스가 생성되게 하는 방법은 없다.
그러나 NSArray, NSDictionary, NSNumber 는 클래스 클러스터이기 때문에,
이 클래스들의 하위 클래스는 거의 만들지 않을 뿐 아니라 하위 클래스로 만들기도 쉽지 않다.
그리고 전반적으로 기능이 이미 잘 구현되어 있기 때문에 하위 클래스를 만들 필요도 거의 없다.
문자열은 커스텀 클래스를 사용할 수 있지만 컴파일러 옵션을 변경해야 한다.
이 옵션을 사용하는 것은 추천되지 않는다.
커스텀 구현에 대해 잘 알지 못한다면 그냥 NSString 을 사용하는 편이 더 낫기 때문이다.
-
문자열, 배열, 사전의 경우 불변 인자(variants)만 리터럴 문법에서 생성할 수 있다.
가변 인자가 필요하면 가변 복사본을 다음과 같은 방법으로 얻을 수 있다.
NSMutableArray *mutable = [@[@1, @2, @3, @4] mutableCopy];
기억할 점
-
문자열, 숫자, 배열, 사전을 생성할 때 리터럴 문법을 사용하라.
일반적인 객체 생성 메서드로 생성하는 것보다 더 명확하고 매우 간결한 방법이다.
-
배열의 인덱스, 사전의 키에 대한 접근은 첨자를 이용하라.
-
리터럴 문법으로 nil 을 배열이나 사전에 삽입하려고 하면 예외를 발생시킬 수 있으므로
배열이나 사전에 들어가는 값이 nil 이 아닌지 늘 확인하라.
'프로그래밍 놀이터 > iOS' 카테고리의 다른 글
[Effecitve Objective-C] #4 전처리기 #define 보다는 타입이 있는 상수를 사용하라 (0) | 2017.07.24 |
---|---|
[Objective-C] Constant(상수) 정의하기 (0) | 2017.07.23 |
[Objective-C] Class Extension 으로 delegate 정의하기 (0) | 2017.07.19 |
[Objective-C] 카테고리 개념 ( Category ) (0) | 2017.07.18 |
[Effecitve Objective-C] #2 헤더에 헤더를 포함하는 것을 최소화하라 (0) | 2017.07.17 |
댓글