这是我在 swift 中的第一个项目,是的,我已经看到关于这个主题的类似问题,我已经阅读了几乎所有内容,但我仍然无法让我的代码工作。
我有一个实现 WKScriptMessageHandler
协议(protocol)的类,以在 iOS 和 WKWebView
中托管的 javascript 之间架起一座桥梁。
在从 javascript 传递的参数中(解释为 NSDictionary
),我有一个名为 _method
的参数,其中包含 javascript 想要调用的 swift 方法名称。
Metod 名称在 swift 方面成功提取,然后我尝试使用 Selector
调用它,这是我失败的地方:
class AppScriptMessageHandler: NSObject, WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
let dict = message.body as! NSDictionary;
let method = dict.value(forKey: "_method") as? String ?? "";
let selector = Selector(method); // method = "getDocumentsFolder"
let ret = perform(selector)?.takeUnretainedValue()
print(ret!)
}
func getDocumentsFolder() -> String {
return "Pippo"
}
}
一切顺利,直到我尝试执行 let ret = perform(selector)
。在这里我得到以下运行时错误:
2018-02-27 15:49:37.279730+0100 wktest[8375:198645] *** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[wktest.AppScriptMessageHandler getDocumentsFolder]: unrecognized selector sent to instance 0x604000019ef0'
我哪里做错了?我也试过将 :
附加到 method
但我仍然遇到同样的错误
在此先感谢您的帮助!
最佳答案
尝试将其更改为 @objc func getDocumentsFolder() -> String
Swift 语言对所有类方法使用 Table Dispatch
。但是要在方法上执行选择器,应该使用 Message Dispatch
调用此方法。
这就是 @objc
关键字正在做的事情 - 它将函数标记为动态的,它将被 Message Dispatch
调用
您可以阅读有关方法分派(dispatch)的更多信息 here
UPD
同意@Hamish 的评论,@objc
不会为 Swift 创建此函数 method dispatch
,而是为 perform(_:)
方法.
关于ios - 在swift中按名称/字符串调用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49011744/