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

标签 ios swift

这是我在 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/

相关文章:

ios - 将 SDWebImage 与解析一起使用

ios - 升级mac os和升级xcode后如何运行 `npm react-native run-ios`?

iphone - 将数据文件导入 didFinishLaunchingWithOptions 字典进行调试?

ios - 如何对齐嵌入在 UITextView 中的图像

ios - 停止 View Controller 上的计时器解雇 swift

ios - 如何为枚举实现的协议(protocol)提供默认实现?

ios - 从Webview窃取Cookie

ios - 如何以编程方式将事件指示器 View 添加到我的 UITableViewController?

swift - 无法从类中访问值

ios - 将框架嵌入到另一个框架中