Google Adsense Side (160x600)



Modern Objective-C 변경점들에 대한 소개

애플 개발자 카페에 올린 글을 옮겨왔습니다.
그래서 일부 내용은 그냥 넘어가세요.

WWDC 2012 Session 405 Modern Objective-C 에 근거한 내용입니다.

자세한 내용은 개발자 사이트로 가서 확인하세요.


제가 직접 저것들을 캡쳐하거나, 이 글에 붙여넣지 못하는 이유는, 애플은 무서운 회사이며 WWDC 는 사실 유료 개발자들에게만 공개되는 애플의 Confidential 자료이기 때문입니다. 그래서 잘못 걸리면 애플 개발자에서 짤리...는 위험성이...

여기는 대부분 유료 개발자일 것이므로 직접 로그인 해서 위 링크를 타고 들어가보세요.

그럼...


...는 훼이크이고...
그래도 이렇게 그냥 넘어가기는 뭐하죠.

어떤 주요 변경이 있는지 대략적인 소개만 하고(그럴수 밖에 없는 것이 Xcode 4.4 부터인데, 그걸 깔 수가 없는 상황),
그리고 그게 뭘 의미하는지 (다소 개인적인) 이야기를 할 것입니다.

Objective-C의 기초적인 내용은 전혀 언급하지 않을 것이며, 추가적인 질문에 대한 설명을 하지는 않을 것입니다.
(내용이 변경되면 수정은할 것임)


Objective-C 의 진화

사실, 매년 WWDC 에서 Objective-C는 크게 변화해 왔습니다.
그러나 따지고 보면 근래들어 근본적인 것이 바뀐 것은 별로 없다고 보입니다.
물론 Block 같은 경우는 근본적이고 큰 변화로 보입니다.

하지만 대부분의 경우 애플의 진화 전략은 한마디로...

너무 길게 쓰기 귀찮은 (그리고 사람이 수동으로 길게 쓰다보면 삑싸리가 나기 쉬운 반복적인) 코드를
컴파일할때 자동으로 만들어서 채워넣겠다.

...라는 것입니다.

그럼 지금까지 있었던 큰 변화에 속하는 property라든가, ARC라든가 그런것들은 뭐냐?
그것들도 따지고 보면 컴파일러가 아래와 같은 짓을 우리 대신 해 주는 것입니다.

@property id attr; @synthesize attr; 이라는 것을 컴파일러가 보면, - (id)attr 하고 - (void)setAttr:(id)newAttr 이런 것들을 대신 써 주거나...
ARC를 켜면, 주변 상황과 메시지 이름 컨벤션을 참고해서 적절하게 retain, release 코드를 넣는다거나...하는 것입니다.

이 말은, ARC 가 있다고 해서 retain/release, 좀 더 근본적으로 ownership transfer 와 관련된 것을 무시하고 몰라도 되는 것이 아니며, 
실제로 뒤에서 어떤 식으로 변환되는지에 대한 기초 지식이 아직까지는 있어야 된다는 것이죠. 

또, 멋대로 메시지 이름을 정하거나 하면 안됩니다. 
Objective-C도 나온지 30여년 가까이 된다는데, 그동안 쌓여온 매우 강력한 코딩 컨벤션들이 있습니다.
그리고 애플의 언어 진화 전략은 저 컨벤션을 토대로 코드를 생성하는 쪽에 집중되어 있습니다.
따라서 다른 언어식의 컨벤션을 고집하지 말고, 반드시 Objective-C의 컨벤션을 알고 따라야 됩니다.

물론, 위 두가지는 제 경험에서 비롯된 개인적인 의견입니다.

이번 Modern Objective-C 도 같은 전략이 사용됩니다.

이번에는 C++11에 추가되었다는 요소들을 도입하고, 또 여러 기초 타입에 대한 새로운 literal을 컴파일러가 인식해서 적절한 코드로 바꿔주는 작업을 하도록 함으로 이전보다 크다고 할 수 있는 변화를 추구했습니다. 이게 표면적으로는 문법적인 추가 혹은 변화이기도 하지만 사실 컴파일러가 코드를 생성해 주는 것이므로, 이전에 어떤 코드로 어떻게 변화하는지 알아둬야 애매한 상황에서 확실하고 안전한 코딩을 할 수 있을 것입니다. 당연히 코드는 처음 보면 생소(하기 보다는 다른 언어의 것들과 유사)하게 보입니다.

제게 크게 중요하게 와 닿지 않았던 부분은 위 링크의 원문들을 참고하시고...
제가 임으로 중요한 점으로 생각되는 변화(추가점?)위주로 소개하도록 하지요.

1. Enum with Explicit Type

typedef enum NSNumberFormaterStyle : NSUInteger { ... } NSNumberFormaterStyle; 

이런식으로 enum에 배정되는 타입을 명시적으로 표기할 수 있습니다. 물론 과거에도 방법이 있긴 있었는데 좀 조잡하고 난잡한 방법들이었다고 합니다. NE_ENUM macro를 써서도 같은 짓을 할 수 있답니다. 이게 중요한 점은 iOS는 32비트, OSX는 64비트 시대이므로, 같은 enum type도 아키텍쳐에 따라 실제 바이트 수가 달라질 수 있기 때문이죠.


2. @synthesize 의 변화

Xcode 4.4 이후부터는 @property만 하고 @synthesize는 안써도 알아서 컴파일러에 의해 추가 될 것입니다. 다만 주의할 점이 있는데, 최근 애플의 예제코드에 자주 등장하는 컨벤션 변화에 따라서 생략한 @synthesize의 경우 자동으로 ivar가 '_' 로 시작하게끔 생성됩니다. 중요한 기본 행동의 변화입니다. 사실 몇해 전에는 ivar를 '_'로 시작하는 것을 하지 말라고 했던 적도 있었습니다. 왜냐면 애플의 private api에 종종 사용되었기 때문이라고 하더군요. 그런데 지금은 그걸 일일히 변경을 했는지 '_' 로 시작하는 컨벤션을 따르랍니다.

@synthesize 자동 추가는 Core Data model 객체인 NSManagedObject 의 경우는 적용되지 않도록 설정했답니다. 
이때는 @dynamic을 계속 써야 됩니다.


3. Object Literal

가장 중요한 추가점이라고 할 수 있습니다. 몇몇 진짜 진짜 자주 쓰여서 코드를 지저분하게 했던 기본적인 타입에 대해 문법적으로 다른 방식으로 쓸 수 있도록 허용(사실은 컴파일러가 코드를 적절하게 풀어서 바꿔줌)했습니다. NSString을 @"..." 이런식으로 생성할 수 있는  것과 비슷한 식의 문법이, 다른 정말 많이 쓰이는 객체들에도 추가된 것이죠.

numberWith... 시리즈는 그냥 @을 앞에 붙이면 끝입니다.

NSNumber * n = [NSNumber numberWithInt: 100];

이렇게 길고 지루하고, 타입도 써줘야 되고 그랬던 것이...

NSNumber * n = @100;

이러면 끝...(이렇게 하면 위 코드로 해석되고, 뭔놈을 어따 대입하느냐 이런것에 따라 타입도 알아서 결정)

NSString의 경우 stringWithUTF8String: 이게 위와같은 적용이 되어서...

NSString *str = [NSString stringWithUTF8String: "바보"];

였지만...이후에는,

NSString *str = @("바보");

이러면 끝...

코드가 매우 간결해 지는 것이 느껴집니다. 물론 처음보면 매우 생소할 것이며, 조만간 Q&A 가 이런 것들로 도배되겠죠.


4. Container/Dictionary Literals

여기서 끝나지 않습니다. NSArray와 NSDictionary도 득을 봅니다.

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

이것은(비디오를 보면 아시겠지만, 정확히는 이걸로 바뀌는 것은 아닙니다)...

NSArray *a = @[ a, b, c ];

이렇게!

NSDictionary *d = [NSDictionary dictionaryWithObjectsAndKeys: v1, k1, v2, k2, nil];

이랬던 것이...

NSDictionary *d = @{ k1 : v1, k2 : v2 };

 이렇게!!
(뭐 일반적인 모습이죠. JSON 생각하면 될 듯)

코드가 획기적으로 줄어들었습니다. 이게 다가 아닙니다...


5. Object Subscripting

이, 이건...위의 변화에서 예측이 된 것이긴 해도...

NSArray *a = @[ a, b, c ];

라면...
a[0], a[1], a[2] ...
이렇게 접근이 가능...
Dictionary 도 당연히 같은 식으로...

이것은 C++에서 [] operation를 오버로딩하는 것과 유사한 지원입니다.
우리도 저게 생성해내는 message를 구현함으로 똑같이 [] operator를 쓸 수 있습니다.

- (id) objectAtIndexedSubscript:(NSUInteger)idx; 뭐 이런 시리즈입니다. 
이것들을 구현해 주면 우리의 클래스 역시 []를 사용 가능해 집니다.


그리고...

이것들은 모두 Xcode 4.4 이후부터 지원이 되구요.
Objective-C++ 에도 비슷한 전략으로 몇가지가 추가되었고,
Core Foundation의 toll-free bridged도 예전하고 좀 더 비슷하게 쓸 수 있도록(__bridged 생략 가능) 해줬답니다.
(뭐! 지금 다 찾아서 __bridged 썼더니!!!!)

또...

옛날에 혜성같이 등장해서 계륵같은 신세였던 Objective-C Garbage Collection 은...

GC가 죽었음다.

Mountain Lion 부터 deprecated 가 되어 버렸습니다.
이건 ARC의 등장시 예견되었던 일이라고 할 수 있는데...
(ARC는 =nil; 을 통해 명시적으로 release 타이밍을 조절 가능)

이것이 OSX 에서만 지원된데다가, 실제 대부분의 개발자들이 외면하는(이거 의존했다구요? 안습이네요. 하지만 마이그레이션 도구를 지원해 준답니다) 신기능이었죠. 저도 한번도 써 본적도 없고, 문서 조차 본 적도 없어요. 어떻게 쓰는줄도 몰라요...--;
대부분 이전 코드나 MRC에 만족(익숙)해 왔던 개발자들이 외면했고, 오히려 개발자 이외의 분들이 자동 GC도 안되는 Objective-C 언어가 낡았음...하는 얘기때문에 구색이나 맞추다가 결국 시들시들해지고 이런 꼴이 났군요. 


아무튼, 이러저러한 변화를 통해 오류를 줄이고, 타 언어 사용자들의 장벽을 낮추기 위한 노력으로 보입니다.

가끔, 오래되신 개발자분들일수록, 이런 변화(사실상 컴파일러의 코드 제네레이션)가 삽질이다! 귀찮다! 옛날식대로 할래! 나는 순혈의 경험많은 원조 Objective-C 개발자걸랑... 이런 경우가 있습니다. 매우 유명한 에피소드로 property에서 '.'을 쓰는 것에 대한 갑론을박 사건이 있었죠. 아론 힐리가스조차 이것은 좀 필요 없고 오히려 혼란은 아닐까...싶다...이런식으로 언급했던 적이 있으니 말 다했죠. 그 밑에 있던 어떤 강사의 경우 신랄하게 property 추가를 깠던 적도 있습니다 (C struct 와 겹친다고)...물론 지금은 그런 주장은 버로우...

물론, 익숙한 것이 좋은 것이요, 익숙한 것이 생산성도 높...을 수도 있죠. 하지만 애플의 경우 대세에 따르는 것이 편합니다.
지금은 하위 호환을 위해 컴파일러가 생성해 주지만, 나중에는 아예 문법처럼 변화될 수도 있고...
(까라면 까야되는 더러운 슈퍼 울트라 깡패 갑 애플님이기도 하니까...)

저는 이런 변화를 적극적으로 수용해야 한다고 생각합니다. 
여러분들은 어떠신지요?

...그건 그래도 상당량의 코드 변화를 수반하는 것은 어쩔 수 없네요. 물론 바이너리단에서 문제는 없답니다. 왜냐면 대부분은 컴파일러님이 우리대신 작업해 주는 것이라서요...






핑백

  • being nice to me : 드디어 Xcode 4.4 ... 속였구나! 애플! 2012-07-27 07:30:07 #

    ... LLVM4와 더불어 Xcode 4.4부터는 Modern Objective-C라는 일부 언어적인 업그레이드가 예고 되었는데... 내용은 이전에 소개한 적이 있죠... property getter/setter, ivar 연결 코드 생성 룰의 변화라든가...Array, Dictionary, Number ... more

덧글

  • lqez 2012/06/29 10:02 # 삭제

    정리해주셔서 감사합니다 :)
  • 2012/07/03 23:40 # 삭제 비공개

    비공개 덧글입니다.
  • 오오 2012/07/04 07:54 #

    어디로 갔는지는 알아야 겠는데...
  • 으랏챠슈퍼된장 2012/08/13 22:18 # 삭제

    굳굳
※ 로그인 사용자만 덧글을 남길 수 있습니다.