Objective C에는 다른 객체로 메시지를 보내는 개념이 있으며 이는 C # 및 Java와 같은 언어로 호출하는 메소드와 매우 유사합니다.
그러나 미묘한 차이점은 정확히 무엇 입니까? 코드를 생각할 때 메시지를 어떻게 생각해야합니까?
참고 : 여기에 약간의 배경 지식이 있으며 Objective C에 대한 몇 가지 개념을 이해하려고하는 C # / Java 개발자입니다.
Objective C에는 다른 객체로 메시지를 보내는 개념이 있으며 이는 C # 및 Java와 같은 언어로 호출하는 메소드와 매우 유사합니다.
그러나 미묘한 차이점은 정확히 무엇 입니까? 코드를 생각할 때 메시지를 어떻게 생각해야합니까?
참고 : 여기에 약간의 배경 지식이 있으며 Objective C에 대한 몇 가지 개념을 이해하려고하는 C # / Java 개발자입니다.
답변:
메시지는 선택기의 이름과 해당 선택기의 매개 변수입니다.
선택기는 심볼입니다.
메소드는 선택기에서 식별 한 클래스의 코드입니다.
즉, 매개 변수 를 사용하여 [foo bar: baz]
호출 된 메시지 를 object로 보냅니다.이 메시지를 여러 다른 개체로 보낼 수 있습니다.@selector(bar:)
baz
foo
반면, 방법 bar:
A에 대한이 Foo
같은 보일 수 있습니다
-(int)bar:(int)n {
return n + 1;
}
하지만 FooTwo
다음과 같이 보일 수도 있습니다.
-(int)bar:(int)n {
return n + 2;
}
(구문이 맞았 으면 좋겠다; Objective-C를 마지막으로 만난 지 오래되었습니다.)
메시지를 보내면 Objective-C 커널은 메시지를 foo
이해하는지 여부를 결정 하는 메시지를 발송합니다 . 해당 선택기로 식별 된 메소드를 찾을 수 있는지 여부에 따라이를 결정합니다.
같은 이름을 가진 두 가지 방법과 하나의 메시지.
객체가 처리를 위해 특정 메시지 (또는 메시지 세트)를 다른 객체로 간단하게 전달할 수도 있습니다. 이 경우, 해당 프록시 객체에 메시지를 전송하는데, 이 메시지 에는 해당 메시지와 일치하는 메소드가 없으며 프록시가 메시지를 랩핑 된 객체로 전달합니다.
순전히 이론적 인 관점에서 볼 때, 둘 사이에는 전혀 차이가 없습니다. 둘이 완전히 동등하다는 것을 보여주는 공식적인 증거가 많이 있으며, 둘 중 하나만 다른 관점에서 구현 될 수 있습니다.
약간 덜 이론적 인 관점에서 한 가지 가능한 차이점이 있습니다. 일반적인 구현에서는 가상 함수 테이블이 정적으로 할당되고 각 vtable의 내용이 컴파일시 고정됩니다. 이와 대조적으로 메시지 조회는 일반적으로 일종의 맵과 유사한 객체로 수행되는데, 이는 일반적으로 동적이므로 런타임시 수정할 수 있습니다. 따라서 기존 클래스의 메시지에 대한 새로운 응답을 비교적 쉽게 추가 할 수 있습니다. 불행히도, 대부분의 경우 이것은 대부분 이론적으로 남아 있습니다. 첫째, 기본적으로 자체 수정 코드를 다루고 있습니다. 대부분의 사람들은 오랫동안 나쁜 생각이라고 결정했습니다.전에. 둘째, 매우 의미가 있으려면 지원하는 새 메시지에 응답하기 위해 새 클래스를 기존 클래스로 컴파일 할 수 있어야합니다. 그것 없이는 기존 메소드의 새로운 이름을 동적으로 추가 할 수 있습니다.
이전 단락의 끝에서 암시 된 것처럼, 실제적인 관점에서이 둘 사이에는 차이가 거의 없습니다. 그들은 늦은 바인딩을 지원하는 두 가지 (매우 약간) 다른 방법입니다. 메시지 기반 조회는 일반적으로 약간 느리지 만 차이가 실제로 중요하다는 것은 매우 드문 일입니다. 가장 실용적인 목적으로, 그들은 동일한 일을 달성하는 두 가지 다른 방법 일뿐입니다.
일반적으로 메소드 호출은 컴파일시 (Java로 리플렉션을 사용하지 않는 한) 해결되며, Objective C의 메시지는 런타임에 전달됩니다.
struct
첫 번째 매개 변수로 사용하는 구문 설탕을 사용하는 것입니다. 후기 결합은 다형성 및 따라서 OOP의 필수 부분이다.
메시지는 커널 또는 언어 자체에 의해 처리됩니다 (예 : ObjC의 경우 매우 작은 어셈블리 코드가 있습니다).
예를 들어 리눅스 커널에서 메시지는 시스템 호출 / 함수로 수행됩니다. 유닉스 시스템 프로그래밍에 대해 검색하면 찾을 수 있습니다.
메소드 호출과 메시지의 핵심 차이점은 다음과 같습니다.
메소드 호출은 코드에서만 발생합니다. ASM에서는 전달 된 인수의 PUSH로 변환됩니다.
커널 메시지는 대부분 커널로 전송 된 것으로 추적되어 특정 프로세스로 다시 전송됩니다. 나는 파이프로 오해 할 수도 있지만 무엇이든 : 이미 여러 프로그램을 동시에 실행하고 동시에 통신 할 수있는 메커니즘이 있다는 것을 알고 있습니다. 물론 이것이 Windows 또는 다른 OS에서 동일한 방식으로 작동하기를 바랍니다.