program tip

Objective C 메시지 디스패치 메커니즘

radiobox 2020. 12. 8. 07:55
반응형

Objective C 메시지 디스패치 메커니즘


저는 Objective C (장난감 iPhone 앱 작성)로 놀아보고 싶고 메시지를 전달하는 데 사용되는 기본 메커니즘에 대해 궁금합니다. C ++의 가상 함수가 일반적으로 구현되는 방식과 정적 또는 비가 상 메서드 호출과 관련된 비용에 대해 잘 알고 있지만 메시지가 전송되는 방식을 알기 위해 Obj-C에 대한 배경 지식이 없습니다. 주변에 찾아 내가 발견 느슨한 기준을 그리고 IMP 빨리 빨리 표준 메시지 보내기보다는 차례에 가상 함수 호출보다되는 메시지를 캐시 언급하고있다.

나는 무엇이든 최적화하려는 것이 아니라 메시지가 정확히 어떻게 전달되는지에 대해 더 깊이 이해합니다.

  • Obj-C 메시지는 어떻게 발송됩니까?
  • 인스턴스 메서드 포인터는 어떻게 캐시되고 메시지가 캐시 될지 코드를 읽어서 알 수 있습니까?
  • 클래스 메서드는 기본적으로 C 함수 (또는 C ++의 정적 클래스 메서드)와 동일합니까, 아니면 더 많은 것이 있습니까?

나는 이러한 질문 중 일부가 '구현에 의존적'일 수 있다는 것을 알고 있지만 실제로 중요한 구현은 하나뿐입니다.


Obj-C 메시지는 어떻게 발송됩니까?

Objective-C 메시지는 런타임의 objc_msgSend()기능을 사용하여 전달 됩니다. Apple 문서에 표시된 이 함수는 최소 2 개의 인수를 사용합니다.

  1. 수신 대상
  2. 메시지 선택자
  3. [전송되는 메시지에 대한 변수의 인수 목록]

클래스의 인스턴스에는 isa클래스 개체에 대한 포인터 인 포인터가 있습니다. 각 객체의 메서드 선택자는 클래스 객체의 "테이블"에 저장되고 objc_msgSend()함수 isa는 클래스 객체에 대한 포인터를 따라이 테이블을 찾고 메서드가 클래스의 테이블에 있는지 확인합니다. 찾을 수 없으면 클래스의 수퍼 클래스 테이블에서 메서드를 찾습니다. 찾을 수없는 경우 메서드를 찾거나 루트 개체 ( NSObject)에 도달 할 때까지 개체 트리를 계속합니다 . 이 시점에서 예외가 발생합니다.

인스턴스 메서드 포인터는 어떻게 캐시되고 메시지가 캐시 될지 코드를 읽어서 알 수 있습니까?

메시징 에 대한 Apple의 Objective-C 런타임 가이드에서 :

메시징 프로세스의 속도를 높이기 위해 런타임 시스템은 사용되는 메서드의 선택기와 주소를 캐시합니다. 각 클래스에 대해 별도의 캐시가 있으며 상속 된 메서드 및 클래스에 정의 된 메서드에 대한 선택기를 포함 할 수 있습니다. 디스패치 테이블을 검색하기 전에 메시징 루틴은 먼저 수신 객체 클래스의 캐시를 확인합니다 (한 번 사용 된 메서드가 다시 사용될 가능성이 있다는 이론에 따라). 메서드 선택기가 캐시에 있으면 메시징이 함수 호출보다 약간 느립니다. 프로그램이 캐시를 "워밍업"할 수있을만큼 오래 실행되면 보내는 거의 모든 메시지가 캐시 된 메서드를 찾습니다. 프로그램이 실행될 때 새 메시지를 수용하기 위해 캐시가 동적으로 증가합니다.

언급했듯이 프로그램이 실행되면 캐싱이 시작되고 프로그램이 충분히 오래 실행 된 후에는 대부분의 메서드 호출이 캐시 된 메서드를 통해 실행됩니다. 또한 언급했듯이 캐싱은 메서드가 사용됨에 따라 발생하므로 메시지는 사용되는 경우에만 캐시됩니다.

클래스 메서드는 기본적으로 C 함수 (또는 C ++의 정적 클래스 메서드)와 동일합니까, 아니면 더 많은 것이 있습니까?

클래스 객체는 클래스 인스턴스와 유사한 방식으로 메소드 발송을 처리합니다. 각 클래스 객체에는 자체 클래스 메서드 를 저장하는 객체가 있습니다 metaclass. 클래스 객체는 자신 isa의 메타 클래스 객체에 대한 자체 포인터를 가지고 있으며 , 이는 다시 클래스 객체를 상속 할 수있는 슈퍼 메타 클래스 객체를 포함합니다. 클래스 메서드에 대한 메서드 디스패치는 다음과 같습니다.

  1. 디스패치 시스템 isa은 메타 클래스 객체에 대한 클래스 객체의 포인터를 따릅니다.
  2. 메타 클래스 객체의 메서드 테이블에서 클래스 메서드를 검색합니다.
  3. 찾을 수없는 경우 검색은 메타 클래스 개체의 수퍼 클래스로 계속 진행되며 검색이 계속됩니다.
  4. 이 프로세스는 메서드가 발견되거나 루트 메타 클래스에 도달 할 때까지 반복되고 예외가 throw됩니다.

나는 또한 누군가가 깊이 들어가고 싶다면 내 웹 로그의 x86_64에서 objc_msgSend ()에 대한 지침 가이드를 작성했습니다.

http://www.friday.com/bbum/2009/12/18/objc_msgsend-part-1-the-road-map/

참고 URL : https://stackoverflow.com/questions/982116/objective-c-message-dispatch-mechanism

반응형