2009-11-08 2 views
4

Objective-C가 모든 메서드 호출에 동적 바인딩을 사용한다는 것을 알고 있습니다. 어떻게 구현됩니까? objective-c는 컴파일 전에 "C 코드로 변환"하고 모든 것에 포인터 (void *)를 사용합니까?Objective-C는 동적 바인딩을 사용하지만 어떻게?

+3

objective-c 런타임은 오픈 소스, btw입니다. 그것은 재미있는 읽기를 만듭니다. objc_msgSend()는 호출시 스택 프레임을 다시 작성할 필요가 없도록 꼬리 호출 최적화를 사용하여 디스패치하는 어셈블리어입니다. 아주 빠릅니다. – bbum

답변

11

개념적으로, 무슨 일이 벌어지고 것은 디스패처 라이브러리 (일반적으로 목표 C 런타임이라고 함)이 있다는 것을, 그리고 컴파일러는 다음과 같이 변환 :

[myObject myMethodWithArg:a andArg:b ]; 

//Not exactly correct, but close enough for this 
objc_msgSend(myObject, "myMethodWithArg:andArg:", a, b); 
로를

그리고 나서 런타임은 모든 바인딩과 디스패치를 ​​처리하고, 적절한 함수를 찾아서 args로 호출합니다. 간단하게 해시 검색과 같은 것으로 생각할 수 있습니다. 물론 현실에서는 훨씬 더 복잡합니다.

메소드 서명과 관련된 문제가 더 많습니다 (C는 유형을 인코딩하지 않으므로 런타임에서이를 처리해야합니다).

4

각 Objective C 메소드는 C 함수 ("사실상")로 구현됩니다. 이 메소드에는 메시지 (텍스트 문자열)가 연관되어 있으며 클래스에는 메시지 문자열과 C 함수가 일치하는 찾아보기 테이블이 있습니다. 따라서 Objective C 메서드를 호출하면 실제로 메시지 문자열을 개체에 보내면 개체는 해당 클래스의 메서드 조회 테이블에서 관련 C 함수를 찾아 실행합니다.

Objective C와 함께 객체를 전달할 때 이해할 수없는 메시지를 처리하는 방법, 메시지와 메소드 조회를 캐시하는 방법 등이 Objective C의 기본 사항입니다.

C++은 메시지 테이블이있는 클래스 대신 "vtable"이라고하는 다른 것을 가지고 있으며 텍스트 문자열을 통하지 않고 vtable로 오프셋을 통해 메서드를 호출합니다. 이는 정적 바인딩의 한 형태이며 실행 속도가 다소 빨라지지만 동적 바인딩보다 유연성이 떨어집니다.

관련 문제