2010년 9월 12일 일요일

object-c objc_msgSend

NSObject isa라는 인스턴스 변수를 갖는다. isa는 객체를 생성하는 클래스구조체를 가리키는 포인터이다.
isa가 가르키는 클래스 구조체는 클래스의 인스턴스 변수, 유형과 이름, class method의 구현, super class의 클래스구조체를 가르키는 포인터 등으로 구성된다.

'selector'는 이 클래스의 method를 색인 한다. selector SEL의 유형을 갖는데, 이는 실제로 char*로 대응된다. (typedef SEL char* 의 의미인듯)
selector는 각 method의 고유한 정수값으로 되어 있다.
이것이 메시지와 갖는 연관성은 다음과 같다.
컴파일 시에 컴파일러는 메시지를 보내야 할 때마다 selector를 찾는다.

addObject selector 12라고 가정하면
[myObject addObjet:yourObject];
objc_msgSend(myObject, 12, yourObject);

objc_msgSend() myObject isa포인터에서 클래스 구조체를 가져온다. 그후 클래스 구조체에서 12에 연결된 method를 찾는다. (해당클래스에 method가 없으면 상위의super class에거 찾는다.




[receiver message]와 같은 구문이 있을때 이 메시지 호출은 objc_msgSend(receiver, selector)메시징 함수로 바뀌어 불리게 된다.

함수형
id objc_msgSend(id theReceiver, SEL theSelector, ...)

파라메터
theReceiver : 메시지를 받게되는 클래스 인스턴스 포인터
theSelector : 호출하고자 하는 클래스 메서드
   ...      : 메서드의 전달 인자 리스트

ReturnValue(id) : 메서드 리턴값

위 함수에서 첫번째 파라메터 id는 구조체이다. 이것은 아래와 같은 형식을 가지고 있다.
typedef struct objc_object
{
    Class isa;
} *id;

typedef struct objc_class *Class;

struct objc_class
{
   struct objc_class* isa;
   struct objc_class* super_class;
   const char* name;
   long version;
   long info;
   long instance_size;
   struct objc_ivar_list* ivars;
   struct objc_method_list** methodLists;
   struct objc_cache* cache;
   struct objc_protocol_list* protocols;
};
위와 같이 id objc_class 구조체의 인스턴스 포인터 변수일 뿐이다.
구조체의 내부를 들여다 보자.

isa는 클래스 정의 포인터를 가진다.(뭔지 잘 모르겠다.)
super_class base 클래스의 pointer를 가진다.
Name
Version
Info
Instance_size
Ivars
methodLists;
cache
protocols