2014-02-11 23 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');"]; 

我相信,JSC包装没有通过第二个参数来将挡,因为记录的第一个参数后va_list崩溃迭代。

我也试过NSArray*惯例,它不起作用。

这有可能以任何方式吗?

+0

我也试着界定了多个ARGS一个Objective-C的控制台日志处理程序时,要做到这一点,但使用NSLogv无法得到它,甚至去。一个混乱的方法 - 您可以尝试通过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 * value){...}')会泄漏传递的值。听起来像块保留了值,上下文保留块,块保留值,并且值保留上下文。 –

1

我喜欢@ erm410的回答,我没有看到currentArguments的文档。

我采取的另一种方法是将JSON对象传递给Objective-C NSDictonary。这种方法的一个好处是你已经命名了参数 - 尽管你正在处理需要在调用和处理程序之间正确输入的字符串文字。

ctx[@"func"] = ^(NSDictionary *args) { 
    NSLog(@"%@", args[@"arg1"]; 
}; 

[ctx evaluateScript:@"func({'arg1':'first','arg2':'second'})"];