I am trying to implement a JSON-RPC solution, using a server connector object wich obtains a list of available functions from a server somehow like
NSDictionary *functions = [server
callJSONFunction: @"exposedFunctions" arguments: nil];
wich is a simplified description, since callJSONFunction
actually triggers an asynchronous NSURLConnection.
An element of the function list consists of a string describing the objective c selector, the original function name wich will be called using the mechanism mentioned above, the function signature and an optional array of argument names.
So for example a function list could look like this:
(
@"someFunctionWithArgumentOne:argumentTwo:" =
{
signature = @"@@:@@",
functionName = @"someFunction",
arguments = ( @"arg_one", @"arg_two" )
},
@"anotherFunction" =
{
signature = @"@@:",
functionName = @"anotherFunction"
}
)
As soon as the function list was successfully retrieved, the selectors are added to the server connector instance using class_addMethod
in a loop:
for ( NSString *selectorName in functions ) {
SEL aSelector = NSSelectorFromString ( selName );
IMP methodIMP = class_getMethodImplementation (
[ self class ], @selector ( callerMethod: ) );
class_addMethod ( [ self class ], aSelector, methodIMP, "v@:@@@@" );
}
where callerMethod:
is a wrapper function used to compose the actual request, consisting of the function name as a NSString and an NSDictionary of the form
{ @"argument1_name" = arg1, @"argument2_name" = arg2, ... }
hence the signature "v@:@@". The callerMethod then invokes callJSONFunction
on the server.
After this exhausting introduction (my bad, I just did not know, how to shorten it) I'll finally get to the point: to cover the possibility of different numbers of arguments,
I defined the callerMethod like
- (void) callerMethod: (id)argument, ... { }
wherein I use the va_* macros from stdarg.h
to obtain the passed arguments. But when I test the mechanism by invoking
[serverConnector someFunctionWithArgumentOne: @"Argument 1"
argumentTwo: @"Argument 2" ];
the first argument returned by id arg = va_arg ( list, id);
is always @"Argument 2"
!
I'd really appreciate all theories and explainations on why that happens. This thing is really driving me nuts!