Objective C 메시지 디스패치 메커니즘
저는 Objective C (장난감 iPhone 앱 작성)로 놀아보고 싶고 메시지를 전달하는 데 사용되는 기본 메커니즘에 대해 궁금합니다. C ++의 가상 함수가 일반적으로 구현되는 방식과 정적 또는 비가 상 메서드 호출과 관련된 비용에 대해 잘 알고 있지만 메시지가 전송되는 방식을 알기 위해 Obj-C에 대한 배경 지식이 없습니다. 주변에 찾아 내가 발견 이 느슨한 기준을 그리고 IMP 빨리 빨리 표준 메시지 보내기보다는 차례에 가상 함수 호출보다되는 메시지를 캐시 언급하고있다.
나는 무엇이든 최적화하려는 것이 아니라 메시지가 정확히 어떻게 전달되는지에 대해 더 깊이 이해합니다.
- Obj-C 메시지는 어떻게 발송됩니까?
- 인스턴스 메서드 포인터는 어떻게 캐시되고 메시지가 캐시 될지 코드를 읽어서 알 수 있습니까?
- 클래스 메서드는 기본적으로 C 함수 (또는 C ++의 정적 클래스 메서드)와 동일합니까, 아니면 더 많은 것이 있습니까?
나는 이러한 질문 중 일부가 '구현에 의존적'일 수 있다는 것을 알고 있지만 실제로 중요한 구현은 하나뿐입니다.
Obj-C 메시지는 어떻게 발송됩니까?
Objective-C 메시지는 런타임의 objc_msgSend()
기능을 사용하여 전달 됩니다. Apple 문서에 표시된 이 함수는 최소 2 개의 인수를 사용합니다.
- 수신 대상
- 메시지 선택자
- [전송되는 메시지에 대한 변수의 인수 목록]
클래스의 인스턴스에는 isa
클래스 개체에 대한 포인터 인 포인터가 있습니다. 각 객체의 메서드 선택자는 클래스 객체의 "테이블"에 저장되고 objc_msgSend()
함수 isa
는 클래스 객체에 대한 포인터를 따라이 테이블을 찾고 메서드가 클래스의 테이블에 있는지 확인합니다. 찾을 수 없으면 클래스의 수퍼 클래스 테이블에서 메서드를 찾습니다. 찾을 수없는 경우 메서드를 찾거나 루트 개체 ( NSObject
)에 도달 할 때까지 개체 트리를 계속합니다 . 이 시점에서 예외가 발생합니다.
인스턴스 메서드 포인터는 어떻게 캐시되고 메시지가 캐시 될지 코드를 읽어서 알 수 있습니까?
메시징 에 대한 Apple의 Objective-C 런타임 가이드에서 :
메시징 프로세스의 속도를 높이기 위해 런타임 시스템은 사용되는 메서드의 선택기와 주소를 캐시합니다. 각 클래스에 대해 별도의 캐시가 있으며 상속 된 메서드 및 클래스에 정의 된 메서드에 대한 선택기를 포함 할 수 있습니다. 디스패치 테이블을 검색하기 전에 메시징 루틴은 먼저 수신 객체 클래스의 캐시를 확인합니다 (한 번 사용 된 메서드가 다시 사용될 가능성이 있다는 이론에 따라). 메서드 선택기가 캐시에 있으면 메시징이 함수 호출보다 약간 느립니다. 프로그램이 캐시를 "워밍업"할 수있을만큼 오래 실행되면 보내는 거의 모든 메시지가 캐시 된 메서드를 찾습니다. 프로그램이 실행될 때 새 메시지를 수용하기 위해 캐시가 동적으로 증가합니다.
언급했듯이 프로그램이 실행되면 캐싱이 시작되고 프로그램이 충분히 오래 실행 된 후에는 대부분의 메서드 호출이 캐시 된 메서드를 통해 실행됩니다. 또한 언급했듯이 캐싱은 메서드가 사용됨에 따라 발생하므로 메시지는 사용되는 경우에만 캐시됩니다.
클래스 메서드는 기본적으로 C 함수 (또는 C ++의 정적 클래스 메서드)와 동일합니까, 아니면 더 많은 것이 있습니까?
클래스 객체는 클래스 인스턴스와 유사한 방식으로 메소드 발송을 처리합니다. 각 클래스 객체에는 자체 클래스 메서드 를 저장하는 객체가 있습니다 metaclass
. 클래스 객체는 자신 isa
의 메타 클래스 객체에 대한 자체 포인터를 가지고 있으며 , 이는 다시 클래스 객체를 상속 할 수있는 슈퍼 메타 클래스 객체를 포함합니다. 클래스 메서드에 대한 메서드 디스패치는 다음과 같습니다.
- 디스패치 시스템
isa
은 메타 클래스 객체에 대한 클래스 객체의 포인터를 따릅니다. - 메타 클래스 객체의 메서드 테이블에서 클래스 메서드를 검색합니다.
- 찾을 수없는 경우 검색은 메타 클래스 개체의 수퍼 클래스로 계속 진행되며 검색이 계속됩니다.
- 이 프로세스는 메서드가 발견되거나 루트 메타 클래스에 도달 할 때까지 반복되고 예외가 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
'program tip' 카테고리의 다른 글
로그인 화면으로 반응 탐색 (0) | 2020.12.08 |
---|---|
블레이드에서 Laravel .env 변수에 액세스 (0) | 2020.12.08 |
이것이 null인지 확인 (0) | 2020.12.08 |
쉘에서 배열의 길이를 찾는 방법은 무엇입니까? (0) | 2020.12.08 |
참조 DLL 파일이 배포 프로젝트로 bin에 복사되지 않아 오류가 발생합니다. (0) | 2020.12.08 |