Objective-C / Cocoa 정리 #1 연구 (study)

** 객체와 클래스

typedef struct objc_class *Class;
typedef struct objc_object {
    Class isa;
} *id;

isa 는 단순히 클래스 객체의 주소값
클래스 객체의 isa 는 메타 클래스의 주소를 가지고 있다.

일반적으로 객체를 할당(alloc) 하면 첫 4 바이트(x86_64 에서는 8 바이트) 는 isa 값이 저장된다.
실제로 아래와 같이 비공식적으로 접근이 가능

CObj *a = [[CObj alloc] init];
void *classObjPtrA = (void *)(*(long *)a); // 클래스 객체의 주소값
void *metaClassPtrA = (void *)(*(long *)classObjPtrA); // 메타 클래스 객체의 주소값

** 메시지 패치 과정

어떤 객체의 instance method 를 호출했을 경우 다음과 같은 과정이 일어난다. (클래스 객체도 비슷한 방식으로 동작한다)

1. 객체의 isa 를 이용해 클래스 객체를 찾는다.
2. 클래스 객체의 method 테이블에서 해당 method 를 찾는다.
3. 찾았다면 해당 method 가 실행되고, 못찾았다면 super_class 에서 다시 찾는다.
4. 찾을때 까지 반복
5. 루트 클래스에서도 못찾았고 5 번 과정이 처음이라면 원래 클래스의 +resolveInstanceMethod: 가 호출되고 2 번부터 다시..
6. -methodSignatureForSelector: 가 호출된다. 
7. 올바른 signature 가 리턴됐다면 -forwardInvocation: 가 호출된다. 아니라면 바로 9 로.. 
8. forwarding 을 못했다면 -forwardInvocation: 는 루트 클래스까지 거슬러 올라가며 호출되도록 한다.
9. doesNotRecognizeSelector: 가 호출되고 예외가 발생한다.

위의 순서보다는, 이러한 전체 과정 속에 dynamic method loading 과 message forwarding 이 숨어있다는게 중요.
(사실 약간 다를 수도 있다... -_-;)

** 셀렉터 관련

C/C++ 에서는 미리 코드상에서 함수의 주소를 알아내거나 가상함수 테이블을 참조해서 주소를 알아낼 수 있지만
오브젝티브-C 에서는 런타임에서 selector 이름으로 실행/연결 시킬 수 있다.

typedef struct objc_selector *SEL;    
typedef id (*IMP)(id, SEL, ...); 

// C 함수 얻기 - selector 는 내부적으로는 C 함수와 같다. 
// 실제로 method 에서 숨겨진 변수 (id self, SEL _cmd) 를 참조 할수 있다.
- (IMP)methodForSelector: (SEL)aSelector;
+ (IMP)instanceMethodForSelector: (SEL)aSelector;

// selector 가 해당 객체에 존재하는지 여부 (message forwarding 을 고려한다면 아래 함수도 직접 오버라이딩해야 함)
- (BOOL)respondsToSelector: (SEL)aSelector;
+ (BOOL)instancesRespondToSelector: (SEL)aSelector;

// forwardInvocation method 가 호출되기 전에 signature 를 구한다. - signature 로 NSInvocation 이 만들어진다.
- (NSMethodSignature *)methodSignatureForSelector: (SEL)aSelector;
+ (NSMethodSignature *)instanceMethodSignatureForSelector: (SEL)aSelector;

// method 를 못찾았을 경우 다시 한번 찾기(second chance) 를 수행하기 전에 호출된다.
+ (BOOL)resolveClassMethod: (SEL)sel AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER;
+ (BOOL)resolveInstanceMethod: (SEL)sel AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER;

참고 자료:
아이폰과 맥 OS X 개발을 위한 Objective-C 2.0 - BJ퍼블릭, Apress
Objective-C : 맥과 아이폰 애플리케이션 프로그래밍 - 한빛미디어, Softbank Creative Corp.
http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjectiveC/ObjC.pdf
http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/ObjCRuntimeGuide.pdf
Objective-C runtime source : http://www.opensource.apple.com/source/objc4/objc4-437.1/

1 2 3 4 5 6 7 8 9 10