2014-02-11 7 views
5

Ich würde gerne eine Funktion im JavascriptCore-Kontext definieren, der eine variable Anzahl von Argumenten benötigt.Variable Argumentliste zu JavascriptCore Block

Etwas wie folgt aus:

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');"]; 

Ich glaube, dass die JSC-Wrapper nicht das zweite Argument der Block nicht besteht, weil auf va_list Abstürze Iterieren nach dem ersten Argument anzumelden.

Ich versuchte auch mit der Konvention, es funktioniert nicht.

Ist das in irgendeiner Weise möglich?

+0

Ich habe auch versucht, dies zu tun, wenn ich einen Objective-C-Konsolen-Log-Handler definiert, der mehrere Argumente akzeptiert, aber selbst mit NSLogv nicht funktioniert. Ein chaotischer Ansatz - Sie könnten versuchen, die Argumente in einem einzigen Argument über JSON zu serialisieren und dann in Ihrem Objective-C-Handler auszupacken. – Mike

+0

Ja, das wäre ein letzter Ausweg Ansatz. Es gibt tatsächlich eine Möglichkeit, dies mit der regulären C-API zu tun, mit 'JSObjectMakeFunctionWithCallback', aber ich möchte diese C-Schnittstelle verlassen, damit ARC den Speicher von JS Value verarbeiten kann. –

Antwort

8

Von 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; 

Führende auf die folgenden:

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

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

Das ist auch eine gute Möglichkeit, JSValue-Objekte aus Argumenten zu holen. Habe gerade herausgefunden, dass JSValues ​​als Blockargumente (wie 'ctx [@" func "] =^(JSValue * value) {...}') die übergebenen Werte verliert. Es klingt, als ob der Block den Wert behält, der Kontext behält den Block, der Block behält den Wert und der Wert behält den Kontext bei. –

1

Ich mag die Antwort von @ erm410, hatte ich nicht in der Dokumentation zu currentArguments gesehen.

Ein anderer Ansatz, den ich gemacht habe, besteht darin, ein JSON-Objekt an ein Objective-C NSDictonary zu übergeben. Ein Vorteil dieses Ansatzes besteht darin, dass Sie Argumente benannt haben - obwohl Sie mit String-Literalen arbeiten, die zwischen dem Aufruf und dem Handler korrekt eingegeben werden müssen.