
댓글/트랙백 토글 댓글 보기-끄기 | 트랙백 보기-끄기
트랙백(먼 댓글) 주소 http://dusthyo.com/trackback/70
트랙백 목록 총 0개의 트랙백이 있습니다.
-
DustHyo 2011/11/27 23:26
트랙백으로 의견을 마음껏 남겨주세요. 다만, 스팸 트랙백은 자제해 주십시오.
댓글/트랙백 토글 댓글 보기-끄기 | 트랙백 보기-끄기
트랙백(먼 댓글) 주소 http://dusthyo.com/trackback/63
트랙백으로 의견을 마음껏 남겨주세요. 다만, 스팸 트랙백은 자제해 주십시오.
runtime을 보조해주기 위해서, 컴파일러는 return type이나 인자 type들을 캐릭터 스트링으로 인코딩해서, 해당 메소드의 selector들과 연결을 시켜줍니다. 이런 것은 다른 용도로도 쓸모가 있기 때문에 @encode()라는 컴파일러 디렉티브를 이용해서 쓸 수 있도록 공개했습니다.
@encode()는 그 타입에 맞는 스트링 인코딩을 반환해 줍니다. 좀더 명확히 말하자면 C의 sizeof() 연산자의 인자로 쓰일 수 있는 것이면 아무거나 다 됩니다.
댓글/트랙백 토글 댓글 보기-끄기 | 트랙백 보기-끄기
트랙백(먼 댓글) 주소 http://dusthyo.com/trackback/62
트랙백으로 의견을 마음껏 남겨주세요. 다만, 스팸 트랙백은 자제해 주십시오.
원래 Objective-C 가 한 어드레스 공간에서 단 한 개의 프로세스로 실행되는 프로그램을 만들기위해서 만들어지긴 했지만, OOP 모델 자체가 프로세스간 통신( interprocess communication ) 에도 잘 맞습니다. 다른 주소 공간에 있는, 즉 다른 태스크를 위한 객체간에, 혹은 같은 태스크라도 다른 thread 를 위한 객체간에 Objective-C 메시지가 왔다 갔다 하는 모습은 쉽게 상상할 수 있습니다.
원격으로 메시지를 보내려면, 그 프로그램은 일단 그 떨어져 있는 receiver( remote receiver )와 통신 체계를 우선 구축해야 합니다. 그럴려면 우선 그 원격 객체에 대한 proxy를 메시지를 보내는 측과 같은 주소 공간에 만들어야 합니다. 일단 이렇게 해놓으면 원격 객체와의 통신은 그 proxy를 통해서 이루어집니다.
받아지는 메시지는 일단 큐에 들어가게 됩니다. 그리고 receiver가 받을 준비가 되면 그 큐에서 하나씩 빼서 보게 됩니다.
Proxy가 하는 것은 원격 객체를 대신하는 것은 아니고, 그 원격 객체를 억세스하는 것도 아닙니다. 즉 원격 객체의 한 카피가 아니라, 단지 메시지를 그 원격 객체에 보내고 그 통신을 관리하는 것입니다. 즉 주된 일은 원격 객체에 대한 로컬 주소를 제공하는 것입니다. 그렇다고 완전히 투명성이 있는 존재는 아닌데, 즉 원격 객체의 인스턴스 변수들을 바로 가져오거나 세팅할 수 없습니다.
보통 원격지에 있는 메시지를 받는 객체는 무명(無名) 혹은 익명(溺名)이겠습니다. 즉 그 클래스 자체는 원격 프로그램 내부에 숨겨져 있게 됩니다. 메시지를 보내는 측에서는 받는 측에 대해서 자세한 정보는 알 필요가 없고, 단지 해당되는 원격 객체가 어떤 메시지에 반응하는 가만 알면 됩니다.
이런 이유로, 원격 메시지를 받는 객체는 자신의 인터페이스를 formal protocol로 공개해야 합니다. 보내는 측과 받는 측이 다 그 protocol을 선언해야합니다.
리모트 메시징에 쓰기 위한 용도로써 몇가지 명령어를 사용할 수가 있는데, Objective-C 는 6개의 다음과 같은 타입을 정해 놓았습니다. 이 타입들은 formal protocol 내에서 메소드를 선언하는데 쓰입니다.
formal protocol에서만 사용
송신자 측은 메시지를 수신자측에 보내기 위해, 수신자측의 프로그램을 기다리다가 보내고, 수신자가 프로세싱하던 것을 다 마치면 그렇다고 송신자측에 indication을 애초에 요청받았던 리턴 값과 함께 보냅니다. 정보가 반환되지 않더라도 수신자가 끝낼때까지 기다리는 것은 두 프로그램이 동기를 하는데 도움이 됩니다.
동기 메시지
수신자는 메시지를 받아서 처리하는 동안 송신자는 그외에 자기가 할일을 할 수가 있습니다. oneway라는 모디파이어를 쓰게 됩니다.
비동기 메시지
oneway가 비록 const처럼 타입을 정의하는 것이긴 하지만, 다른 타입 이름과 같이 쓸 수도 있습니다. 즉 oneway float나 oneway id같이 말입니다. 임의의 타입을 지정할때는 oneway void라고 하면 되겠습니다. 이런 비동기 메시지는 리턴값을 가지지 않습니다.
pass-by-reference 이용해서 정보넘기기
정보 리턴
즉 포인터는 송신자측의 주소 공간에 있는 위치를 가르치게 되어서 수신측에서는 의미가 없게 됩니다. 그러므로 runtime 시스템이 여기에 어떤 조정을 가하게 됩니다.
pass-by-reference를 이용하는 인자를 쓰면, runtime 시스템은 그 포인터를 dereference하게 됩니다. 그리고 그 포인터가 가르키고 있는 위치의 내용을 원격 프로그램에 보냅니다. 그리고 그 원격 프로그램의 로컬 주소 공간에 저장하고, 그 주소를 원격 프로그램에 전달합니다. 그러므로 송신측과 수신측의 pointer가 가르키고 있는 메모리 위치는 달라집니다.
반면에 pass-by-reference 스타일로 정보를 리턴할때는, 수신측의 포인터가 가르치는 메모리 위치가 송신측에 보내지진 않습니다. 단지 그 내용이 송신측에서 애초에 수신측에 보낼때 사용했던 그 메모리 위치에 들어가게 됩니다.
이런 메커니즘을 위해서 런타임 시스템이 송신/수신에 대해서 다른 행동을 취해야 하므로, Objective-C는 프로그래머가 의도를 명확하게 표시하도록 타입 모디파이어를 제공합니다.
- setTune:(in struct tune *)aSong:
- getTune:(out struct tune *)theSong:
- adjustTune:(inout struct tune *)theSong:
분산 객체 시스템에서는 포인터를 자동으로 dereferencing해서 그게 가르키는 것을 value인양 전달해 줍니다. 그러므로 out과 inout 모디파이어는 캐릭터 포인터에 대해서 이렇다하게 특별하게 처리해 주질 않습니다. 그러므로 스트링을 pass-by-reference로 전달하려면 한단계 더 간접적인 방식을 취해야 합니다.
객체 역시 마찬가지입니다.
수신자가 그 객체를 proxy를 통해서 접근하고자 한다면, (왜냐하면 그 객체가 수신측의 주소 공간에 있지 않으니까 ) 같은 객체를 가르키고 있지 않게 됩니다. 수신측이 받는 것은 proxy에 대한 id이지 원래의 객체에 대한 id가 아닙니다. proxy에 보내진 메시지는 물론 실제의 객체로 전달은 되고, 반환 역시 마찬가지입니다.
proxy를 사용하는게 불필요하게 비효율적일때가 있습니다. 이럴때는 차라리 그 객체의 카피본을 원격 프로세스에 직접 보내고, 수신측에선 직접 그 객체를 자신의 주소 공간에서 억세스하는 편이 났습니다. 이렇게 하기위해서 Objective-C는 bycopy라는 모디파이어를 제공하고 있습니다.
값 반환
pass-by-reference를 이용하는 경우, 즉 pointer를 이용하는 경우는 out과 함께 쓸 수 있습니다.
objective-c 언어 차원에서 객체간의 통신과 다른 태스크(스레드, 프로세스) 간의 통신의 장벽을 "객체 메세지"를 통해 추상화시킨 모습인거 같아요. 대신 객체 통신의 범위가 태스크 단위가 되면 병렬 스레드에 대한 추가적인 처리를 해야하기 때문에 위에 소개된 키워드들이 있는듯. 여튼 이번 단원은 저자가 발로 쓴듯.
댓글/트랙백 토글 댓글 보기-끄기 | 트랙백 보기-끄기
트랙백(먼 댓글) 주소 http://dusthyo.com/trackback/61
트랙백으로 의견을 마음껏 남겨주세요. 다만, 스팸 트랙백은 자제해 주십시오.