【问题标题】:Calling function by name / string in swift快速按名称/字符串调用函数
【发布时间】:2018-02-27 15:02:12
【问题描述】:

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

我有一个实现WKScriptMessageHandler 协议的类,以提供iOS 和WKWebView 中托管的javascript 之间的桥梁。

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

方法名称在 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 但我仍然遇到同样的错误 提前感谢您的帮助!

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    尝试改成@objc func getDocumentsFolder() -> String

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

    这就是 @objc 关键字正在做的事情 - 它将函数标记为动态,它将被 Message Dispatch 调用

    您可以阅读有关方法调度的更多信息here

    UPD

    同意@Hamish 的评论,@objc 不会使这个函数method dispatch 用于 Swift,而是用于perform(_:) 方法。

    【讨论】:

    • 有效!太好了谢谢!我还有一个问题:在返回值上使用.takeUnretainedValue() 是否正确?我希望它在使用 in 后被垃圾收集。还是我还必须调用 .autorelease() 方法?
    • 好的,我在这里找到了 sanwer:stackoverflow.com/questions/29048826/…
    • @objc 实际上与方法调度没有太大关系,它只是将方法暴露给 Obj-C;如果可能的话,Swift 仍然会使用 table 甚至直接调度来调用该方法。 dynamic 属性是强制 Swift 使用消息调度调用方法的原因。当然,如果方法是通过 Obj-C 运行时调用的,例如在这种情况下使用 perform(_:),将使用消息调度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2021-05-07
    • 2011-12-17
    • 1970-01-01
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多