美文网首页程序员
WKWebView循环引用问题之addScriptMessage

WKWebView循环引用问题之addScriptMessage

作者: 香蕉你个菠萝 | 来源:发表于2022-10-25 14:26 被阅读0次

    WKWebView 初始化时,有一个参数叫configuration,它是WKWebViewConfiguration类型的参数,而WKWebViewConfiguration有一个属性叫userContentController,它又是WKUserContentController类型的参数。
    WKUserContentController对象有一个方法-addScriptMessageHandler:name:
    初始化webView

    lazy var webView: WKWebView = {
            let webCfg: WKWebViewConfiguration = WKWebViewConfiguration()
            let preferences = WKPreferences()
            preferences.javaScriptEnabled = true
            preferences.javaScriptCanOpenWindowsAutomatically = false
            var userController: WKUserContentController = WKUserContentController()
            /// 注册JS的方法
            userController.add(self, name: "requestDeviceChannel")
            webCfg.userContentController = userController
            webCfg.preferences = preferences
            let webView = WKWebView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height), configuration: webCfg)
            webView.tintColor = .clear
            return webView
        }()
    
    • addScriptMessageHandler:name:有两个参数,第一个参数是userContentController的代理对象,第二个参数是JS里发送postMessage的对象。

    当前控制器关闭后,这时我们会发现deinit不会被调用,也就是说控制器对象没有释放。问题就出现在:

    • 1、// addScriptMessageHandler 很容易导致循环引用

    • 2、// 控制器 强引用了WKWebView,WKWebView copy(强引用了)configuration, configuration copy (强引用了)userContentController

    • 3、// userContentController 强引用了 self (控制器)

    解决:打破强引用。让userContentController的代理对象变成VKFlowWebBaseVCProxyHandler。

            /// 解决【addScriptMessageHandler】引起WKWebView循环引用
            let proxy = VKFlowWebBaseVCProxyHandler()
            proxy.webVC = self
           
             /// 注册JS的方法
           //userController.add(self, name: "requestDeviceChannel")       
            userController.add(proxy, name: "requestDeviceChannel")
    

    VKFlowWebBaseVCProxyHandler里的webVC用weak修饰。

    
    class VKFlowWebBaseVCProxyHandler: NSObject, WKScriptMessageHandler {
        
        weak var webVC: VKFlowWebBaseViewController?
        
        func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
            VVLogger.debug(message.body)
            VVLogger.debug("VKFlowWebVCProxyHandler: message name: \(message.name)")
    
    

    相关文章

      网友评论

        本文标题:WKWebView循环引用问题之addScriptMessage

        本文链接:https://www.haomeiwen.com/subject/gtrgzrtx.html