在swift中按名称/字符串调用函数

时间:2018-02-27 15:02:13

标签: ios swift

这是我在swift中的第一个项目,是的,我已经看到有关于这个主题的类似问题已经存在,我几乎已经阅读了所有内容,但我仍然无法使代码正常工作

我是一个实现WKScriptMessageHandler协议的类,用于在WKWebView中提供iOS与托管javascript之间的桥梁。

在从javascript传递的参数中(解释为NSDictionary),我有一个名为_method的名称,其中包含javascript想要调用的swift方法名称。

在swift方面成功提取了Metod名称然后我尝试使用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,但我仍然遇到同样的错误 在此先感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

尝试将其更改为@objc func getDocumentsFolder() -> String

Swift语言对所有类方法使用Table Dispatch。但是为了在方法上执行选择器,应该使用Message Dispatch调用此方法。

这就是@objc关键字的作用 - 它的标记功能是动态的,它将使用Message Dispatch调用

您可以阅读有关方法调度here

的更多信息

<强> UPD

同意@Hamish评论,@objc不会为Swift创建此函数method dispatch,而是perform(_:)方法。