Objective-C 메시지 전달 메커니즘 상세 설명

Objective-C 언어 에서 방법의 전달 은 두 가지 가 있다.① Selector ② Blocks.본 고 는 주로 selector 를 말 하고 Blocks 에 대해 후속 적 으로 정리 할 것 이다.
메시지 전달 모델(Message Passing)은 Objective-C 언어의 핵심 메커니즘 이다.Objective-C 에 서 는 이런 표현 을 사용 할 방법 이 없고 메시지 만 전달 된다.
C++또는 자바 에서 클래스 를 호출 하 는 방법 은 Objective-C 에서 클래스 에 메 시 지 를 보 냅 니 다.C++또는 자바 에 서 는 클래스 와 클래스 의 행동 방법 간 의 관계 가 매우 밀접 합 니 다.하나의 방법 은 반드시 하나의 클래스 에 속 하고 컴 파일 할 때 이미 연결 되 어 있 기 때문에 클래스 에 없 는 방법 을 호출 할 수 없습니다.한편,Objective-C 에 서 는 비교적 간단 합 니 다.클래스 와 메시지 간 에 느슨 한 결합 입 니 다.방법 호출 은 특정한 클래스 에 만 메 시 지 를 보 냅 니 다.이 종 류 는 실행 할 때 받 은 메 시 지 를 어떻게 처리 하 는 지 확인 할 수 있 습 니 다.즉,하나의 클래스 가 반드시 받 은 메시지 에 응답 할 것 이 라 고 보장 하지 않 습 니 다.만약 에 처리 할 수 없 는 메 시 지 를 받 았 다 면 프로그램 이 잘못 되 거나 지연 되 지 않 을 것 입 니 다.그것 은 아무것도 하지 않 고 nil 로 돌아 갑 니 다.[필 자 는 컴 파일 기간 에 틀 리 지 않 고 의미 적 인 이해 에 부합 되 지만 runtime 이 실 행 될 때 무 너 집 니 다]이런 디자인 자체 도 소프트웨어 의 은유 에 비교적 부합된다.아주 nice,인터넷 에서 봤 어 요.copy 가 왔어요)
분명히 컴 파일 러 가 포 지 셔 닝 방법 을 찾 지 않 는 이상 운행 기 포 지 셔 닝 방법 만 있 습 니 다.Objective-C 는 어떻게 운행 기 포 지 셔 닝 방 위 를 찾 습 니까?
id objc_msgSend(id receiver,SEL selector,...)[필요 한 두 가지 매개 변 수 를 포함 합 니 다:receiver(수용자 대상),selector(방법 선택 기)와 알 수 없 는 매개 변수(selector 의 매개 변수 목록)]
Objective-C 는 상기 방법 을 통 해 호출 방법 을 찾 는 것 입 니 다~예 를 들 어[itNoob cry]는 obbc 로 바 뀌 었 습 니 다.msgSend(itNoob,cry),여기 receiver 는 itNoob 대상 이 고 selector 는 cry 선택 기 입 니 다.물론 cry 가 인 자 를 가지 고 있다 면 똑 같이 전 환 됩 니 다.예 를 들 어[tNoob cry:@"엉엉"AndSmile:@"히히"]는 obbc 로 전 환 됩 니 다.msgSend(itNoob,cry:AndSmile:,@"엉엉",@"히히"),obbc 와 유사msgSend(id receiver, SEL selector, parm1,parm2,...)。
objc_msgSend 의 동적 바 인 딩 과정
receiver 대상 에 따라 selector 방법의 구체 적 인 실현 위치 호출 에서 찾 은 실현 을 찾 고 전달 매개 변 수 는 방법 이 실 현 된 반환 값 을 자신의 반환 값 으로 되 돌려 줍 니 다.
그럼 obj cmsgSend 는 어떻게 방법의 구체 적 인 실현 위 치 를 찾 습 니까?인터넷 에서 찾 아 보 았 습 니 다.다음 과 같 습 니 다.
컴 파일 러 가 각 종 류 를 구축 할 때 각 종 류 는 두 가지 필요 한 요 소 를 포함 해 야 합 니 다.부모 클래스 의 지침 을 가리 키 는 스케줄 러(dispatch table),스케줄 러 는 클래스 의 selector 를 방법의 실제 메모리 주소 와 연결 시 켜 야 합 니 다.
우 리 는 모든 대상 이 하나의 isa 지침 을 가지 고 소속 류 를 가리 키 는 것 을 알 고 있 습 니 다.이 isa 지침 을 통 해 대상 의 소속 류 와 소속 부 류 를 찾 을 수 있 습 니 다.
찾기 과정 은 다음 과 같 습 니 다:

대상 이 메 시 지 를 보 내 려 면 isa 에 따라 소속 클래스 를 찾 은 다음 dispatch table 을 찾 아 보 세 요.찾 지 못 하면 부모 클래스 에서 찾 아 보 세 요.찾 으 면 스케줄 러 의 메모리 주소 에 따라 이 를 호출 합 니 다.마지막 에 nil 을 찾 지 못 하면 되 돌아 갑 니 다.

좋은 웹페이지 즐겨찾기