【问题标题】:Swift: Variadic in @objc_block for function in JSContextSwift:@objc_block 中的可变参数用于 JSContext 中的函数
【发布时间】:2015-04-09 00:39:48
【问题描述】:

我在 Swift 中使用 JavaScriptCore,并且想将 javascript 函数设置为 swift objc_block。

这在没有可变参数的情况下效果很好:

var log : @objc_block (String, String, String) -> Void = { string1, string2, string3 in
   println("log:\(string1), \(string2), \(string3)")
 }
context.objectForKeyedSubscript("console").setObject(unsafeBitCast(log, AnyObject.self), forKeyedSubscript: "log");
// invoking console.log("arg1", "arg2", "arg3") will print log:arg1, arg2, arg3

但是使用可变参数我得到一个错误:

var log : @objc_block (String...) -> Void = { string in
  // do some logging
}

在 JavaScript 中抛出并用 context.exceptionHandler 捕获的错误是:

TypeError: Cannot convert primitive to NSArray

如果它试图将 javascript (primitives) 中的参数转换为我在 swift 块中所期望的数组,这是有道理的。要么有一些魔法在 JSContext 中没有发生,要么我做错了(我只使用了 swift 几个小时)。

完整代码为:

let context = JSContext()
context.evaluateScript("var window = this; var console = {};")
context.exceptionHandler = { context, exception in
  println("JS Error: \(exception)")
}
var log : @objc_block (String...) -> Void = { string in
  // do some logging
}
context.objectForKeyedSubscript("console").setObject(unsafeBitCast(log, AnyObject.self), forKeyedSubscript: "log");

【问题讨论】:

  • 我正在寻找如何获取 Swift 代码的 Javascript 回调,并在您的问题中使用 @objc_block 和 unsafeBitCast(..., AnyObject.self) cast 发现了这个问题。只有在我同时应用它们之后才开始为我工作。谢谢!

标签: swift javascriptcore


【解决方案1】:

你应该在 ObjC/Swift 中声明你的函数如下:

JSContext *context = [[JSContext alloc] init];
context[@"func"] = ^void() {
    NSArray *arguments = [JSContext currentArguments];
    ...
};
[context evaluateScript:@"func(2, 3, 4, 1)"];

【讨论】:

  • 这是正确的。你可以在 Swift 中使用JSContext.currentArguments()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-11
  • 1970-01-01
相关资源
最近更新 更多