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