views:

664

answers:

3

Hi,

I would like to code a proxy that forwards method invocations to another object over TCP without NSConnection and NSDistanceObject stuff. What I want is my own protocol.

The problem is that subclassing NSProxy and overriding forwardInvocation: is not sufficient. I have also to override methodSignatureForSelector

Here is my question:

– (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
    return ??? 
}
A: 

The way NSDistantObject handles this is by its setProtocolForProxy: method, which specifies a protocol containing the list of methods that the object on the other end of the connection handles. It can then use the information for these methods to provide appropriate NSMethodSignature objects when doing forwarding.

It looks like the most straightforward to do that is via the protocol_getMethodDescription() function, declared in <objc/runtime.h>. This returns an objc_method_description struct which contains a types field. I believe you should be able to pass that value into +[NSMethodSignature signatureWithObjCTypes:] to get a method signature object that matches what's declared in the protocol.

Brian Webster
+2  A: 

@Brian, This may be ok, but setProtocolForProxy: is just for optimization. cocoafan could mandate it for his solution, but it wouldn't be a drop-in replacement. You're supposed to be able to get signatures automatically. To do that, the network protocol needs a way to request the signature.

I believe the solution here is to include in the network protocol a "request method signature" method, and have it run methodSignatureForSelector: on the distant object and encode and return the result. That's what NSDistantObject does.

Providing setProtocolForProxy: is an important optimization if you're going to chatter a lot, but it does restrict you to objects that you have a protocol for, and prior to 10.5 that introduces some annoying limitations (all methods are required). Even on 10.5, it may introduce some problematic limitations if it's the only way to get method signatures.

@cocoafan, I think you're probably right to create this from scratch on top of NSProxy, but do take a look at NSConnection and see if you can sub-class it to manage the network connection the way you want. If you can find a way to do that (though I don't see an easy way right off), you'll probably get a lot of stuff for free from NSDistantObject.

Rob Napier
Advice taken, thanks to both of you. I will replace the communication with XML-RPC. I'm not sure if this is possible by overriding NSConnection.
cocoafan
A: 

I found a smart solution to generate NSInvocation objects.

cocoafan