Skip to main content

02A. 객체와 메시지

Less than 1 minuteObjective-Ccrashcoursexcodeobjective-cobjc

02A. 객체와 메시지 관련

목차
OSX 구조를 이해하면서 배우는 Objective-C

메시지 표현식

모든 클래스에서 객체는 id라는 특별한 형태로 표현 됩니다. 따라사 다음처럼 객체를 지향하는 변수 obj를 선언합니다.

id obj;

어떤 객체 obj에 메시지 msg를 보내려면 다음처럼 쓰고 메시지 표현식(message expression)이라고 부릅니다.

메시지 표현식은 리시버 객체가 그 메시지를 처리한 결괏값을 돌려줍니다. 즉, 메시지 표현식은 C 함수 호출처럼 다루면 됩니다. 메시지 표현식은 다른 표현식의 구셩 요소로 사용해도 되며 void형을 돌려주는 메시지 표현식도 있습니다.

메시지를 받는 쪽, 즉 위에서 본 obj이라고 적힌 부분에는 객체를 나타내는 표현식도 작성할 수 있습니다. 따라서 어떤 메시지 표현식의 결과가 객체라면 다음처럼 이어서 메시지를 보내도 됩니다.

[[ obj msg1 ] msg2 ];
[[[ obj msg1 ] msg2 ] msg3 ];

.C에서 []는 배열 요소를 참조하는 연산자이지만 Objective-C에서는 메시지 표현식을 의미합니다. 왼쪽에 배열명이나 포인터 같은 다른 표현식이 있을 떄만 []가 배열 연산자입니다. 메시지 표현식의 값을 그대로 배열 인덱스로 쓸 떄는 다음처럼 씁니다.

element = table[[ obj count ]];

메세지는 변수명처럼 식별자와 같은 규칙으로 만들어진 메시지 키워드로 구성됩니다. 함수 호출과 마찬가지로 메시지는 인수가 따라오기도 합니다. 인수가 없는 메시지는 하나의 메시지 키워드로만 이루어집니다. 몇 가지 예를 들어봅시다.

[aString copy];
width = [node width];
[[doc filename] retain];

두 번째 예처럼 변수명과 메시지 키워드명이 같아도 됩니다. 메시지 표현식 속에서 무엇이 메시지 키워드인지 구별할 수 있기 때문입니다.

메시지에 인수가 있으면 메시지 키워드 끝에 콜론(;)을 붙여 인수가 있음을 나타냅니다. 콜론 뒤에는 실인수가 옵니다. 실인수는 함수 호출과 마찬가지로 일반 표현식을 적습니다. 다른 메시지 표현식을 실인수로 써도 됩니다.

[printInfo setLeftMargin: 60.0];
[[[cw window] firstResponder] copy: sender];
[doc isSameDirectory: [info objectAtIndex: ++num]];

인수를 두 개 이상 사용하려면 콜론을 붙이고 다른 키워드를 추가합니다. 또는 키워드 없이 콜런만 추가해도 문법적으로는 문제가 없습니다. 하지만 콜론 없이 키워드만 추가할 수는 없습니다.

cell = [albumview cellAtRow: i column: j];
[maanger fileExistsAtPath:dirname isDirectory:&isdir];
[view lineTo: 1.4142 : (y + 1.0)];

메시지 셀렉터

함수를 함수명으로 호출하는 것처럼 각각의 메시지는 키워드를 나열한 것을 마치 이름처럼 써서 다른 메시지와 구별합니다. 이것을 메시지 셀렉터(message selector) 또는 셀렉터(selector)라고 부르면 메서드명 이라고도 합니다.

앞서 본 메시지 표현식 예에서 몇몇 메시지는 다음과 같은 셀렉터를 가집니다. 인수가 있는 키워드는 콜론도 셀렉터에 포함되므로 주의해야 합니다. 예제의 copycopy:는 서로 다른 셀렉터입니다.

copy
retain
firstResponder
copy:
objectAtIndex:
cellAtRow:column:
fileExistsAtPath:isDirectory:
lineTo::

메시지 키워드는 변수의 명명규칙에 따라 이름을 지으며, 소문자로 시작하는 것이 관례입니다. 여러 단어로 된 셀렉터는 첫 잔어를 제외한 단어 첫 글자마다 대문자로 표기합니다.

띄어쓰기를 하지 않아도 문자열의 의미를 쉽게 알 수 있습니다.[1] Objective-C는 스몰톡의 특징이 여러 부분에서 보이는데 이렇게 메시지를 메시지 키워드로 표현하는 방법도 스몰톡에서 가져왔습니다.

메시지에 인수가 있으면 메시지 전체가 영어 문장처럼 읽히도록 메시지 키워드를 쓴느 것이 관례입니다. 또한 인수가 여러 개라면 메시지 키워드는 각각의 인수가 무엇을 뜻하는지를 나타냅니다. 예를 들어 cellAtRow: column:이라는 셀렉터는 가로 세로로 놓여진 셀(GUI 부품 중 하나)에서 행과 열을 지정한 하나의 셀을 참조할 때 쓰는데, 두 인수 중 무엇이 행이고 열인지 이름으로 바로 알 수 있습니다. 영어 문장으로 봐도 '~행에서 ~열에 있는 셀'로 읽힙니다

인수마다 메시지 키워드를 대응시키면 프로그램이 길어지지만 코드의 가독성은 좋아집니다. "세번째 인수가 무슨 역할이였지?"라면서 메뉴얼을 뒤적거리지 않아도 되어 편리합니다. 대신에 프로그램을 작설할 때 셀렉터를 틀리지 않게 적어야만 합니다. 따라서 클래스 래퍼런스 등에서 셀렉터를 복사해서 붙여 넣는 것이 좋습니다. Mac OS X에서 제공한느 통합 개발환경인 Xcode[2]에는 메서드명 자동 완성 기능이 있습니다.

여러 개의 메시지 키워드로 구성된 셀렉터는 순서를 바꾸면 안 됩니다. 예를 들어 dragFile:fromRect:slideBack:event:라는 셀렉터가 이걸 dragFile:event:slideBack:fromRect:처럼 쓸 수는 없습니다. 두 셀렉터는 전혀 다른 셀렉터 입니다.


인스턴스 생성과 초기화

id형 변수를 선언하는 것만으로는 변수에 객체가 저장되지 않습니다. 객체에 일을 시키려면 우선 클래스에서 인스턴스를 생성해야 합니다.

.Objective-C는 클래스에 메시지를 보내서 인스턴스를 생성합니다. 클래스에 메시지를 보내는 처리는 '4.5절'에서 자세히 설명하므로 여기에서는 클래스명에 메시지 alloc을 보내면 인스턴스가 새로 하나 만들어진다는 것만 기억해 둡시다.

// 인스턴스 생성
[ 클래스명 alloc]

이렇게 만든 인스턴스는 메모리에 필요한 영역이 확보되었다는 것일 뿐이므로 보통은 이 다음에 바로 초기화해야 합니다. 초기화 메서드는 초기자*(initializer)라고 부릅니다. 초기자 역할을 하는 메서드로 무엇이 이ㅆ을지는 클래스마다 다르며, 클래스에 따라서 여러가지 초기자를 제공하기도 합니다.

Cocoa는 초기자가 init이거나 메서드명이 init으로 시작돼야 합니다. 다음은 클래스에서 인스턴스를 만드는 기본 메시지 표현식입니다.

// Cocoa에서 사용하는 인스턴스 생성
[[ 클래스명 alloc ] init ]

인스턴스를 생성할 때 늘 이렇게 alloc 메시지 표현식 다음에 바로 초기자가 오도록 적는 습관을 기릅시다.

초기화가 인스턴스 정보를 '리셋(reset)'하지는 않습니다. 초기자에서 하는 초기화는 인스턴스가 생성된 직후 한 번만 이루어집니다. 인스턴스 변숫값을 초깃값으로 돌리는 등의 리셋에 해당되는 처리가 필요하면 초리자가 아닌 다른 메서드를 사용해야 합니다.

또한 alloc 이외에도 객체를 생성하는 클래스 메서드가 있으며 클래스에서 초기화를 끝낸 다음 인스턴스를 돌려주기도 합니다.


이찬희 (MarkiiimarK)
Never Stop Learning.

  1. 명명규칙은 '부록 C'를 참고하세요 ↩︎

  2. Mac OS X의 'X'는 로마자 숫자로 'Ten(10)'이라고 읽지만 Xcode는 엑스코드라고 읽습니다. ↩︎