美文网首页iOS之报错上架填坑iOS学习笔记iOS Developer
WKWebView与JS交互内存不释放问题探究

WKWebView与JS交互内存不释放问题探究

作者: 程序sky | 来源:发表于2017-04-25 12:01 被阅读609次

    最近在做一个项目,里面用到了与H5的交互,准确的说是JS端要调用本地的代码,这里要说一下,wkWebView的JS交互与普通的UIWebView是不一样的,而且在JS端代码的编写也是有所不同的,希望大家能跟后台人员做良好的沟通。 废话不多说,直接上代码。。。。

    • 先说说wkWebView与JS交互的方法吧
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    
    [config.userContentController addScriptMessageHandler:self name:@"与后台约定的方法名"];
    
    //创建webView
    
    WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:config];
    
    webView.navigationDelegate = self;
    

    在上面的这个方法里面去创建一个webView,并且约定方法名称。

    执行本地的方法时候调用下面的这个方法

    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    //message.body 可以打印JS端给你传过来的数据,可以根据数据去执行相应的方法
    }
    

    你以为JS调用本地的方法就完事了吗?





    错误,你会发现这样调用方法之后,内存根本不释放。也就是说dealloc方法不会执行。

    前方高能,请仔细查看。。。。

    问题就出现在
    [config.userContentController addScriptMessageHandler:self name:@"与后台约定的方法名"];
    这句代码上面,准确的说是“self”的身上。

    那么怎么解决呢?
    我们可以把self换掉,就是说用其他换掉self,这里面就要新建一个类
    在.h里面是这样的

    #import <WebKit/WebKit.h>
    
    @interface XLWeakScriptMessageDelegate : NSObject<WKScriptMessageHandler>
    
    
    @property (nonatomic,weak)id<WKScriptMessageHandler> scriptDelegate;
    
    - (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate;
    
    @end
    

    在.m里面是这样的

    #import "XLWeakScriptMessageDelegate.h"
    
    @implementation XLWeakScriptMessageDelegate
    
    - (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate{
        self = [super init];
        if (self) {
            _scriptDelegate = scriptDelegate;
        }
        return self;
    }
    
    - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
        [self.scriptDelegate userContentController:userContentController didReceiveScriptMessage:message];
    }
    
    @end
    

    新建的类我都写在这里了,大家可以拿过去直接用。
    下面说的是最重要的改动,就是把

    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    
    [config.userContentController addScriptMessageHandler:self name:@"与后台约定的方法名"];
    

    这里面的代码改造成

    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
        [config.userContentController addScriptMessageHandler:[[XLWeakScriptMessageDelegate alloc] initWithDelegate:self] name:@"callback"];
        //创建webView
        WKWebView *webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:config];
        webView.navigationDelegate = self;
    

    这样以来,你就会发现,内存释放了,dealloc的方法可以快快乐乐的执行了。

    第一次发简书,写的不好大家多多见谅,如有什么问题给我留言,我看到一定第一时间给大家回复。

    能帮到你,才是我最大的成就!!!!!

    相关文章

      网友评论

      • 洁简:iOS11.3这个方法不起作用了.
        洁简:@陈_某_某 是的 不走时因为我用了setURLSchemeHandler导致的
        陈_某_某:走的呀
      • 萧城x:ios9 会崩溃
        程序sky:@Jason_cjc 是我写的这个方法会崩溃吗?
        萧城x:找到了 是 scrollview delegate 的问题 == nil 就行了
        程序sky:@Jason_cjc 这真不知道,我们公司没有9的机器 没测过
      • ad193b2e3cf5:朋友,我想请教一下,我想再wkwebview里面加载一个网页游戏。用原生的登录界面,与js交互,也就是说我的主页面只有一个wkwebview。里面注册很多[config.userContentController addScriptMessageHandler:self name:@"与后台约定的方法名"]这种方法。。我需要长时间留在这个页面,那我怎么解决内存的问题呢?
        因为我发现玩一段时间后会出现白屏。。。如果我reload的话,需要重新登录。请问有什么办法解决没有
        ad193b2e3cf5:@程序sky 恩,我还是觉得wkwebview有很多不可预知性,webview也有内存问题。
        我都怀疑是不是苹果出webview的时候就是不让人长时间停留。
        程序sky:@ad193b2e3cf5 这H5里面的游戏,原生的也控制不到吧 除非你把网页关掉才能释放内存,你要是reload的话,所有的数据不是都没有了吗?这肯定不行啊。。。 这优化我觉得应该是H5那粒去处理
      • 阿顺_cbbe:解决了困扰我好久的问题,赞一个!
      • 与伟大LEE同行:方法挺好的 , 不过要注意那个类的释放 不然就泄露咯:+1: +1: +1: +1: +1: +1:
        与伟大LEE同行:@时光的书 在webview的父视图对象中 dealloc方法内 [_webView.configuration.userContentController removeScriptMessageHandlerForName:@""];
        奋进的小时光_Joe:请问那个WeakScriptMessageDelegate类要怎么释放啊
      • 2bd7e62c5187:确实有用,点个赞

      本文标题:WKWebView与JS交互内存不释放问题探究

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