2014-02-11 2 views
5

Я хотел бы определить функцию в контексте JavascriptCore, которая принимает переменное количество аргументов.Переменный список аргументов в блок JavascriptCore

Что-то вроде этого:

JSVirtualMachine* virtualMachine = [[JSVirtualMachine alloc] init]; 
JSContext* ctx = [[JSContext alloc] initWithVirtualMachine:virtualMachine]; 

ctx[@"func"] = ^(JSValue* value, ...){ 
    va_list args; 
    va_start(args, value); 
    for (JSValue *arg = value; arg != nil; arg = va_arg(args, JSValue*)) { 
     NSLog(@"%@", arg); 
    } 
    va_end(args); 
}; 

[ctx evaluateScript:@"func('arg1', 'arg2');"]; 

Я считаю, что ОАО обертка не проходит второй аргумент блока, потому что итерация на va_list аварий после входа в первый аргумент.

Я также пробовал с соглашением NSArray*, он не работает.

Возможно ли это в любом случае?

+0

Я также пытался это сделать, когда определял обработчик журнала Objective-C, который занимал несколько аргументов, но не мог добиться этого даже при использовании NSLogv. Беспорядочный подход - вы можете попробовать сериализовать args в один аргумент через JSON, а затем распаковать его в свой Objective-C-обработчик. – Mike

+0

Да, это был бы последний подход. На самом деле есть способ сделать это, используя обычный C API, с 'JSObjectMakeFunctionWithCallback', но я хотел бы уйти от этого интерфейса C, чтобы ARC могла обрабатывать память JS Value. –

ответ

8

От JSContext.h:

// This method may be called from within an Objective-C block or method invoked 
// as a callback from JavaScript to retrieve the callback's arguments, objects 
// in the returned array are instances of JSValue. Outside of a callback from 
// JavaScript this method will return nil. 
+ (NSArray *)currentArguments; 

ведущий к следующему:

ctx[@"func"] = ^{ 
    NSArray *args = [JSContext currentArguments]; 
    for (JSValue *arg in args) { 
     NSLog(@"%@", arg); 
    } 
}; 

[ctx evaluateScript:@"func('arg1', 'arg2');"]; 
+0

Это также отличный способ получить объекты JSValue из аргументов. Просто выяснили, что получение JSValues ​​в качестве блочных аргументов (например, 'ctx [@" func "] =^(значение JSValue *) {...}') утечки переданных значений. Похоже, что блок сохраняет значение, поэтому контекст сохраняет блок, блок сохраняет значение, а значение сохраняет контекст. –

1

Мне нравится ответ @ erm410, я не видел документацию по currentArguments.

Другой подход, который я принял, - передать объект JSON объекту-объекту C-NS. Одно из преимуществ этого подхода состоит в том, что вы назвали аргументы - хотя вы имеете дело со строковыми литералами, которые нужно правильно вводить между вызовом и обработчиком.

Смежные вопросы