Я пытаюсь реализовать решение JSON-RPC, используя объект коннектора сервера, который получает список доступных функций с сервера, например,
NSDictionary *functions = [server
callJSONFunction: @"exposedFunctions" arguments: nil];
, что является упрощенным описанием, поскольку callJSONFunction
фактически запускает асинхронный NSURLConnection.
Элемент списка функций состоит из строки, описывающей селектор объекта c, исходное имя функции, которое будет вызываться с использованием механизма, упомянутого выше, сигнатура функции и необязательный массивимена аргументов.
Так, например, список функций может выглядеть следующим образом:
(
@"someFunctionWithArgumentOne:argumentTwo:" =
{
signature = @"@@:@@",
functionName = @"someFunction",
arguments = ( @"arg_one", @"arg_two" )
},
@"anotherFunction" =
{
signature = @"@@:",
functionName = @"anotherFunction"
}
)
Как только список функций был успешно получен, селекторы добавляются в экземпляр соединителя сервера с помощью class_addMethod
в цикле:
for ( NSString *selectorName in functions ) {
SEL aSelector = NSSelectorFromString ( selName );
IMP methodIMP = class_getMethodImplementation (
[ self class ], @selector ( callerMethod: ) );
class_addMethod ( [ self class ], aSelector, methodIMP, "v@:@@@@" );
}
, где callerMethod:
- это функция-обертка, используемая для составления фактического запроса, состоящая из имени функции в виде NSString и NSDictionary формы
{ @"argument1_name" = arg1, @"argument2_name" = arg2, ... }
отсюда и подпись "v @: @@".Затем callerMethod вызывает на сервере callJSONFunction
.
После этого изнурительного вступления (мой плохой, я просто не знал, как его сократить), я наконец доберусь до сути: чтобы скрыть возможностьПо разному количеству аргументов я определил метод callerMethod как
- (void) callerMethod: (id)argument, ... { }
, в котором я использую макросы va_ * из stdarg.h
для получения переданных аргументов.Но когда я проверяю механизм, вызывая
[serverConnector someFunctionWithArgumentOne: @"Argument 1"
argumentTwo: @"Argument 2" ];
, первый аргумент, возвращаемый id arg = va_arg ( list, id);
, всегда @"Argument 2"
!
Я действительно ценю все теории и объяснения того, почему это происходит,Эта штука действительно сводит меня с ума!