메시지와 방법의 차이점은 무엇입니까?


13

Objective C에는 다른 객체로 메시지를 보내는 개념이 있으며 이는 C # 및 Java와 같은 언어로 호출하는 메소드와 매우 유사합니다.

그러나 미묘한 차이점은 정확히 무엇 입니까? 코드를 생각할 때 메시지를 어떻게 생각해야합니까?

참고 : 여기에 약간의 배경 지식이 있으며 Objective C에 대한 몇 가지 개념을 이해하려고하는 C # / Java 개발자입니다.


2
그것들은 모두 다른 언어이기 때문에 차이점은 미묘하지 않습니다. 그들은 다른 언어입니다. "내 코드에 대해 생각할 때"? 어떤 코드? Java 또는 C #에 대해 생각할 때 메시지에 대해서는 생각하지 않습니다. 당신은 방법에 대해 생각합니다. 관련없는 개념을 가진 관련없는 언어가 어떻게 "미묘한"차이를 가질 수 있는지 명확히 할 수 있습니까?
— S.Lott

1
stackoverflow.com에 질문하십시오
— Amir Rezaei

1
이 질문이 실제로 StackOverflow에 있어야합니까? 내가 가진 코드에 대해서는 문제가 아닌 프로그래밍 개념에 대한 질문입니다. 어쩌면 내가 틀렸어, 난 몰라-경계가 흐려져 ...
— Vidar

1
@Vidar, 질문은 주관적이지 않습니다. 당신은 교과서 정의를 찾고 있습니다. 프로그래머는 의견, 경험 및 주관적인 질문에 더 적합합니다.
— Stephen Furlani

1
OK-중재자 가이 질문을 StackOverflow로 옮길 수있는 방법이 있습니까?
— Vidar

답변:


10

메시지는 선택기의 이름과 해당 선택기의 매개 변수입니다.

선택기는 심볼입니다.

메소드는 선택기에서 식별 한 클래스의 코드입니다.

즉, 매개 변수 를 사용하여 [foo bar: baz]호출 된 메시지 를 object로 보냅니다.이 메시지를 여러 다른 개체로 보낼 수 있습니다.@selector(bar:)bazfoo

반면, 방법 bar: A에 대한이 Foo같은 보일 수 있습니다

-(int)bar:(int)n {
  return n + 1;
}

하지만 FooTwo다음과 같이 보일 수도 있습니다.

-(int)bar:(int)n {
  return n + 2;
}

(구문이 맞았 으면 좋겠다; Objective-C를 마지막으로 만난 지 오래되었습니다.)

메시지를 보내면 Objective-C 커널은 메시지를 foo이해하는지 여부를 결정 하는 메시지를 발송합니다 . 해당 선택기로 식별 된 메소드를 찾을 수 있는지 여부에 따라이를 결정합니다.

같은 이름을 가진 두 가지 방법과 하나의 메시지.

객체가 처리를 위해 특정 메시지 (또는 메시지 세트)를 다른 객체로 간단하게 전달할 수도 있습니다. 이 경우, 해당 프록시 객체에 메시지를 전송하는데, 이 메시지 에는 해당 메시지와 일치하는 메소드가 없으며 프록시가 메시지를 랩핑 된 객체로 전달합니다.


그래서 ... 메시지는 dispinterface (a.invoke selector, args)를 호출 할 때이고 메소드는 인터페이스 (a.methodName)을 호출 할 때입니까? Java, JavaScript, 모든 동적 언어가 메시지를 가지지 않습니까? 모든 것이 직접 점프하지 않고 이중 인터페이스를 통해 발생하고 vtable 점프로 오프셋되기 때문에)?
— Dmitry

4

순전히 이론적 인 관점에서 볼 때, 둘 사이에는 전혀 차이가 없습니다. 둘이 완전히 동등하다는 것을 보여주는 공식적인 증거가 많이 있으며, 둘 중 하나만 다른 관점에서 구현 될 수 있습니다.

약간 덜 이론적 인 관점에서 한 가지 가능한 차이점이 있습니다. 일반적인 구현에서는 가상 함수 테이블이 정적으로 할당되고 각 vtable의 내용이 컴파일시 고정됩니다. 이와 대조적으로 메시지 조회는 일반적으로 일종의 맵과 유사한 객체로 수행되는데, 이는 일반적으로 동적이므로 런타임시 수정할 수 있습니다. 따라서 기존 클래스의 메시지에 대한 새로운 응답을 비교적 쉽게 추가 할 수 있습니다. 불행히도, 대부분의 경우 이것은 대부분 이론적으로 남아 있습니다. 첫째, 기본적으로 자체 수정 코드를 다루고 있습니다. 대부분의 사람들은 오랫동안 나쁜 생각이라고 결정했습니다.전에. 둘째, 매우 의미가 있으려면 지원하는 새 메시지에 응답하기 위해 새 클래스를 기존 클래스로 컴파일 할 수 있어야합니다. 그것 없이는 기존 메소드의 새로운 이름을 동적으로 추가 할 수 있습니다.

이전 단락의 끝에서 암시 된 것처럼, 실제적인 관점에서이 둘 사이에는 차이가 거의 없습니다. 그들은 늦은 바인딩을 지원하는 두 가지 (매우 약간) 다른 방법입니다. 메시지 기반 조회는 일반적으로 약간 느리지 만 차이가 실제로 중요하다는 것은 매우 드문 일입니다. 가장 실용적인 목적으로, 그들은 동일한 일을 달성하는 두 가지 다른 방법 일뿐입니다.


3
증거를 보여주는 참고 자료가 있습니까? 한 번 살펴보고 싶습니다. 바인딩의 지연뿐만 아니라 발신자와 수신자의 분리로 인해 Java의 메소드 호출과 스몰 토크의 메시지 전송 간에는 큰 차이가 있습니다. 메시지의 수신자가 메시지를 처리하는지 또는 메시지를 전달 하는지를 알 수 없습니다. 예를 들어.
— Frank Shearar

@ FrankShearar : 죄송합니다. 내가 본 증거는 인쇄되었고, OOP와이를 구현하는 방법이 오래 전부터 그러한 것들에 대한 증거가 학자들에게 흥미로울 정도로 충분히 새롭습니다.
— Jerry Coffin

1

Objective-C에서 메시지는 지연됩니다. 즉, 런타임시 해결됩니다. C #은 객체를 늦게 바인딩 된 것으로 선언하는 Dynamic 키워드를 통해 유사한 구문을 지원합니다.


0

일반적으로 메소드 호출은 컴파일시 (Java로 리플렉션을 사용하지 않는 한) 해결되며, Objective C의 메시지는 런타임에 전달됩니다.


2
메서드 호출이 컴파일 시간으로 해결되면 OOP를 사용하지 않고 오버로드 된 함수에 대해 struct첫 번째 매개 변수로 사용하는 구문 설탕을 사용하는 것입니다. 후기 결합은 다형성 및 따라서 OOP의 필수 부분이다.

2
예. 그러나 여전히 컴파일 타임에 잘 알려진 것 (Java)에 대해서만 메소드 호출을 코딩 할 수 있습니다. MyObject 또는 MyInterface에 foo () 메서드가 정의되어 있지 않은 경우 MyObject.foo ()를 호출하면 오류가 발생합니다. ObjC는 MyObject 객체에 'foo'라는 메시지를 보낼 수 있으며 MyObject에 'foo'가 없으면 런타임시 폭탄이 터집니다.
— Heiko Rupp

목표 C가 컴파일 된 언어라고 생각 했습니까?
— Vidar

1
그것은 초기 / 늦은 바인딩에 비현실적입니다 (동적 타이핑 대 구조적 typig-예제에서 메소드 호출은 컴파일 타임에 확인 되지만 반드시 전달 되지는 않습니다 ). @Vidar : 그렇습니다. 그러나 동적 기능에 마법을 더합니다. 파이썬을 컴파일 할 수도 있습니다.

@ Vidar : 컴파일 된 vs. 해석 된 문제가 아니라 정적 대 동적 문제입니다. Java와 같은 정적 OOP 언어에서 컴파일러는 컴파일 단계에서 클래스가 메소드를 정의하는지 확인합니다. Objective-C와 같은 동적 유형 언어에서 메시지는 런타임에 전달됩니다.
— mipadi

-1

메시지는 커널 또는 언어 자체에 의해 처리됩니다 (예 : ObjC의 경우 매우 작은 어셈블리 코드가 있습니다).

예를 들어 리눅스 커널에서 메시지는 시스템 호출 / 함수로 수행됩니다. 유닉스 시스템 프로그래밍에 대해 검색하면 찾을 수 있습니다.

메소드 호출과 메시지의 핵심 차이점은 다음과 같습니다.

  • 메소드 호출은 코드에서만 발생합니다. ASM에서는 전달 된 인수의 PUSH로 변환됩니다.

  • 커널 메시지는 대부분 커널로 전송 된 것으로 추적되어 특정 프로세스로 다시 전송됩니다. 나는 파이프로 오해 할 수도 있지만 무엇이든 : 이미 여러 프로그램을 동시에 실행하고 동시에 통신 할 수있는 메커니즘이 있다는 것을 알고 있습니다. 물론 이것이 Windows 또는 다른 OS에서 동일한 방식으로 작동하기를 바랍니다.


프로그래밍 언어에 적용되는 "메시지 전달"이 아닙니다.
— mipadi
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.