2010-05-17 6 views
49

C 또는 ECMAscript 기반 언어에서 개체에 대해 공용 메서드 또는 함수를 호출합니다. 그러나 Objective C의 설명서에는 공용 메서드 호출이없고 메시지 만 전송됩니다.Objective C에서 '메서드 호출 중'또는 '메시지 보내기'

ObjC에서 '메시지 보내기'를 할 때 실제로 '개체에 대한 공용 메서드 호출'이라고 생각하는 데 문제가 있습니까?

+0

+1 큰 질문입니다. 이 두 가지의 차이를 이해하면 Objective-C의 유연성을 이해하는 데 도움이됩니다. –

+4

이것에 대해 안전하게 "Nil에게 메시지 보내기"라고 생각하면 Null에서 안전하게 "메서드 호출"할 수 있습니까? –

답변

53

이론적으로 그들은 다릅니다.

실제로는 그렇게 많지 않습니다.

Objective-C의 경우 개체가 메시지에 응답하지 않거나 다른 개체로 메시지를 전달할 수 있다는 점이 다릅니다. C와 같은 언어에서 함수 호출은 실제로 메모리와 실행 코드의 특정 지점으로 점프하고 있습니다. 동적 인 행동이 필요 없습니다.

그러나 표준 사용 사례에서 메시지를 개체로 보낼 때 메시지가 나타내는 메서드는 일반적으로 호출됩니다. 따라서 약 99 %의 시간 동안 메시지를 보내면 메서드가 호출됩니다. 따라서 우리는 실제로 "메시지 보내기"를 의미 할 때 "방법 호출"이라고 종종 말합니다. 실제적으로, 그들은 거의 항상 같은 것입니다, 그러나 그들은 일 필요는 없습니다.

A는 얼마 전, 나는이 주제에 대한 철학적 왁스 칠하고 그것에 대해 블로그 : http://davedelong.tumblr.com/post/58428190187/an-observation-on-objective-c

편집

직접 귀하의 질문에, 말을 아무 문제는 일반적으로 없다 "메소드를 호출"대신에 대답하려면 "메시지 보내기". 그러나 매우 중요한 구현 차이점이 있음을 이해하는 것이 중요합니다.

(그리고 옆으로, 내 개인적인 취향은 "객체의 메소드를 호출"말처럼) 아니, 그런 그것의 생각과 전혀 아무 문제가

+1

블로그 링크를 업데이트 할 수 있습니까? – pooya72

+0

아직 어떤 형태로 액세스 할 수 있다면 블로그 게시물을 보는 데 관심이 있습니다. – obeattie

+1

@obeattie 업데이트 됨 –

-5

자바 클래스에서이 사실을 알게되었습니다. 필자는 메시지 전달이 매우 합법적이며 자주 사용되는 기술인 멀티 스레드 시나리오에서만 현실적인 차이점이 있다고 말합니다.

3

없습니다. 메시지는 기능에 대한 추상화 계층이기 때문에 메시지라고합니다. 이 중 일부는 Objective C의 유형 시스템에서 비롯됩니다. 메시지의 더 나은 이해하는 데 도움이 :

full source on wikipedia 함수의

내부 이름은 거의 직접 사용하지 이다 (나는 더 많은 관련 문제의 일부를 골랐다). 일반적으로 메시지는 Objective-C 런타임 라이브러리에 정의 된 호출로 변환됩니다. 수신기의 클래스 ( 메시지를 전송하는 대상)의 클래스가 런타임까지 알 필요가 없으므로 링크 시간에 알려진 메서드가 호출되는 것은 아닙니다. 을 호출 할 필요는 없습니다.같은 문서에서

: 객체 지향 프로그래밍의 목적-C 모델 객체 인스턴스 전달하는 메시지에 를 기초

. Objective-C에서는 메서드를 호출하지 않습니다. 하나는 메시지를 보낸다. 메시지가 전달되는 대상 - 수신자 - 은 메시지에 응답하지 않을 수 있으며, 그렇지 않은 경우 은 예외를 발생시킵니다. 스몰 토크 스타일 프로그래밍 은 메시지를 구현하지 않고 메서드를 사용하여 런타임에 구현 된 으로 해결합니다. 예를 들어 의 경우 개체 컬렉션으로 메시지가 전송 될 수 있습니다. 일부는 응답 할 것으로 예상되며 오류가 발생할 염려가 없습니다. (A 코코아 응용 프로그램의 모든 개체가 로 awakeFromNib 전송으로 코코아 플랫폼이의 활용 :.. 애플리케이션 출시로 메시지를 출시에 필요한 초기화를 실행하여 응답 할 수 오브젝트) 메시지 전달도 않습니다 객체가 컴파일시 시간에 정의되도록 정의 할 필요가 없습니다.

18

Objective-C의 동적 메시징 디스패치 때문에 메시지 전송은 실제로 C 함수 또는 C++ 메서드를 호출하는 것과 다릅니다 (결국 C 함수가 호출되지만). 메시지는 선택자를 통해 수신 객체로 보내지며 IMP (C 함수 포인터)을 호출하거나 메시지를 수퍼 클래스로 전달하여 메시지에 응답합니다. 상속 체인의 클래스가 메시지에 응답하지 않으면 예외가 throw됩니다. 또한 메시지를 가로 채서 완전히 다른 클래스로 전달할 수도 있습니다 (이것은 서브 클래스가 수행하는 것입니다).

목표 - C를 사용하여, 메시지 전송 및 C++ 사이에 큰 차이가없는 - 스타일 메소드 호출하지만, 내가 알고있는 메시지 전달 시스템의 몇 가지 실제적인 의미가있다 :

  1. 은 메시지 처리는 런타임에 수행되기 때문에 컴파일 시간 대신 클래스가 특정 메시지에 응답하는지 여부를 알 수있는 컴파일 타임 방법이 없습니다. 따라서 대개 메서드를 잘못 입력하면 오류 대신 컴파일러 경고가 표시됩니다.
  2. nil으로 안전하게 메시지를 보낼 수 있으며 NULL 확인 여부를 걱정하지 않고 [foo release]과 같은 숙어를 허용합니다.
  3. @CrazyJugglerDrummer에 따르면 메시지 발송을 사용하면 응답 할 것인지에 대한 걱정없이 한 번에 많은 개체에 메시지를 보낼 수 있습니다. 이렇게하면 비공식 프로토콜을 사용하고 컨테이너의 모든 개체에 메시지를 보낼 수 있습니다.
  4. 100 % 확신 할 수는 없지만 동적 메시지 전달을 통해 카테고리 (이미 존재하는 클래스에 메소드 추가)가 가능하다고 생각합니다.
  5. 메시지 전송은 메시지 전달을 허용합니다 (예 : NSProxy 하위 클 래스 사용).
  6. 메시지 보내기를 사용하면 메서드 swizzling (런타임시 메서드의 구현 교환)과 같은 흥미로운 저급 해킹을 수행 할 수 있습니다.
+3

틀림없이, 나는 Objective-C 초심자이지만'[foo release]'를 의미하지 않습니까? – sblom

1

컴파일러는 선택기를 함수 호출로 바꾸고 함수 호출에 대한 응답으로 실행을 점프합니다.

Objective-C 방법은 메시지에 동적으로 바인딩됩니다. 즉, 메소드 이름은 런타임에 구현으로 해석됩니다. 특히 런타임에 객체가 검사되어 주어진 선택자에 대한 구현에 대한 포인터가 포함되어 있는지 확인합니다.

결과적으로 Objective-C를 사용하면 실행 중에 새로운 클래스와 범주를로드하고 연결할 수 있으며 스위 즐링, 범주, 개체 프록시 등의 기술을 수행 할 수 있습니다. 이 중 어느 것도 C에서 가능하지 않습니다.

관련 문제