본문 바로가기
프로그래밍/iOS

Objective-C에 새로 추가된 NSDictionary, NSArray, NSNumber 리터럴(literal) 표기법

by 백룡화검 2013. 7. 12.

출처 : http://cafe.naver.com/mcbugi/255479


지난해 XCode 4.4가 배포되면서 탑재된 LLVM 4.0 컴파일러는 Objective-C에 새로운 리터럴 표기법을 사용할 수 있도록 했습니다. NSString에서 리터럴 표기법은 @""였습니다. 이와 유사하게 NSArrayNSDictionaryNSNumber에 대해서도 아래와 같이 추가되었습니다. 


NSArray 리터럴 


이전:

array = [NSArray arrayWithObjects:a, b, c, nil];


현재:

array = @[ a, b, c ];



NSDictionary 리터럴 


이전:

dict = [NSDictionary dictionaryWithObjects:@[o1, o2, o3] forKeys:@[k1, k2, k3]];


현재:

dict = @{ k1 : o1, k2 : o2, k3 : o3 };



NSNumber 리터럴 


이전:

NSNumber *number;

number = [NSNumber numberWithChar:'X'];

number = [NSNumber numberWithInt:12345];

number = [NSNumber numberWithUnsignedLong:12345ul];

number = [NSNumber numberWithLongLong:12345ll];

number = [NSNumber numberWithFloat:123.45f];

number = [NSNumber numberWithDouble:123.45];

number = [NSNumber numberWithBool:YES];



현재:

NSNumber *number;

number = @'X'; //char

number = @12345; //int

number = @12345ul; //unsigned long

number = @12345ll; //long long

number = @123.45f; //float

number = @123.45; //double

number = @YES; //bool


사례를 보면서 이해하기

조금더 확인해 보겠습니다. 


아래처럼 NSNumber를 간편하게 쓸 수 있게 되었습니다.

NSNumber *n;

n = @42;                    //[NSNumber numberWithint:42];

n = @10.8;                 //[NSNumber numberWithDouble:10.8];

n = @YES;                  //[NSNumber numberWithBool:YES];

n = @(6 + x * 2012); //[NSNumber numberWithint:6 + x * 2012];


문자열도 뭔가 프리미티브한 형태의 제약에서 벗어났습니다. 

NSString *path = @( getenv("PATH") ); //[NSString stringWithUTF8String: getenv("PATH")];


흥미로운 것은 다음 표기법을 쓸 수 있다는 겁니다.

arr[@1]         === [arr objectAtIndex:1]

dict[@"key"]   === [dic objectForKey:@"key"]


NSArray와 NSDictionary에서 요소에 접근시 다음처럼 할 수 있습니다. 정말 생산성이 달라집니다.

NSArray *arr = @[a, b, c];  //[NSArray arrayWithObjects: a, b, c, nil]

arr[i];                               //[arr objectAtIndex:i]


NSDictionary *dic = @{k1:v1, k2:v2}; //[NSDictionary dictionaryWithObjectsAndKeys: v1, k1, v2, k2, nil];

dic[k];                                              //[dic valueForKey:k]



그러니깐 이걸 좀 응용하면 배열의 replace를 다음처럼 할 수 있습니다.

NSMutableArray *_songs;

_songs[0] = [[NSObject alloc] init]; //[_songs addObject:[[NSObject alloc]init]]

_songs[1] = [[NSObject alloc] init]; //[_songs addObject:[[NSObject alloc]init]]

Song *oldSong = _songs[idx]; //Song *oldSong = [_songs objectAtIndex:idx];

_songs[idx] = newSong;        //[_songs replaceObjectAtIndex:idx withObject:newSong];


비슷한 방법으로 NSDictionary도 할 수 있습니다.

NSMutableDictionary *_storage;

id oldObject = _storage[key];  //id oldObject = [_storage objectForKey:key];

_storage[key] = newObject;   //[_storage setObject:object forKey:key]; 


참고로 리터럴 표기법(literal notation)이란 프로그램 언어가 미리 정의해 놓은 매크로입니다.


언어가 리터럴 표기법을 제공하면 왠만하면 쓰는게 장땡입니다. ^^


작성자 : 지돌스타(http://blog.jidolstar.com/842