财富坊cff888 /
  • WKWebView /
  • 循环引用 /
  • 背景

    项目中使用了WKWebView替换了之前的UIWebView,牵扯到Hybird开发,我们需要和H5交互,所以用到了WKWebViewConfiguration 中的 WKUserContentController

    所以初始化代码如下

    
            WKUserContentController *userContentController = [[WKUserContentController alloc] init];
            [userContentController addScriptMessageHandler:self name:GetKeyiOSAndroid_Action];
            [userContentController addScriptMessageHandler:self name:Upload_Action];
    
            // WKWebView的配置
            WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
            configuration.userContentController = userContentController;
    
            _webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
            _webView.navigationDelegate = self;
            _webView.UIDelegate = self;

    GetKeyiOSAndroid_Action Upload_Action 分别是H5通过message handler的方式来调用OC的两个方法。

    这时,就已经发生了隐患,因为

    [userContentController addScriptMessageHandler:self name:GetKeyiOSAndroid_Action];

    这里userContentController持有了self ,然后 userContentController 又被configuration持有,最终呗webview持有,然后webview是self的一个私有变量,所以self也持有self,所以,这个时候有循环引用的问题存在,导致界面被pop或者dismiss之后依然会存在内存中。不会被释放

    当然如果你只是静态界面,或者与H5的交互的内容仅限于本页面内的内容,其实只是单纯的内存泄漏,但是,如果此时和H5的交互方法中牵扯到全局变量,或者全局的一些内容,那么就不可控制了。

    我发现这个问题是因为我们web页面会监听token过期的和登录状态改变的通知,然后会刷新界面,并且重新发送请求,这一系列动作中会和用户的全局信息进行交互,所以在访问一个web页面后,切换账号登录时会发现有之前访问过的web页面请求发出,并且因为token不同报了token过期的错误,所以导致登录后误操作为token过期,紧接着被踢到登录界面。

    通过charles抓包发现,这些web页面都是在切换登录账号欠访问的所有界面,所以,锁定问题时web页面依旧存在,在切换登录后收到了登录状态改变的通知,重新刷新了界面导致请求发出并返回报错,进而出现登录后被踢出的bug。

    解决方案:

    既然是循环引用,那么必须破除一边的强引用,改为弱引用,或者直接去除引用。思路明朗了。。

    尝试1:

    id __weak weakSelf = self;
    WKUserContentController *userContentController = [[WKUserContentController alloc] init];
    [userContentController addScriptMessageHandler:weakSelf name:GetKeyiOSAndroid_Action];

    思路效仿block , 结果失败

    尝试2:

    viewWillDisappear / viewDidDisappear 生命周期方法中调用

    [_webView.configuration.userContentController removeAllUserScripts];
    

    这算一个脑抽的尝试,看文档说明就懂了。自行略过

    这里写图片描述

    尝试3:

    不在初始化时添加ScriptMessageHandler, 而是和Notificenter/KVC一个思路

    - (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
    
        [_webView.configuration.userContentController addScriptMessageHandler:self name:GetKeyiOSAndroid_Action];
        [_webView.configuration.userContentController addScriptMessageHandler:self name:Upload_Action];
    }
    
    - (void)viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear:animated];
    
        [_webView.configuration.userContentController removeScriptMessageHandlerForName:GetKeyiOSAndroid_Action];
        [_webView.configuration.userContentController removeScriptMessageHandlerForName:Upload_Action];
    
    }

    结果成功

    小结:

    之前在使用WKWebView的时候很多blog的内容都只是说了怎么添加Message Handler 但是并没有高速大家有这个内存泄漏的风险,如果你只是页面内的数据调用你压根都不会发现这个问题。

    此坑已填!

    阅读全文
    版权声明:本文为博主原创文章,未经博主允许不得转载。

    WebKit(WKScriptMessageHandler)

    WKScriptMessageHandler
    • y550918116j
    • y550918116j
    • 2015年12月01日 20:31
    • 15585

    WKWebView与JS交互

    WKWebView是苹果在iOS8推出的,用来替换UIWebView,相比UIWebView,WKWebView速度更快,占用内存更少。 Objective-C与JS交互的办法大致有: 1、UIW...
    • shenhuaikun
    • shenhuaikun
    • 2017年03月13日 15:06
    • 4196

    wkwebview与js通信学习总结(二) 之MessageHandler

    使用WKWebView的时候,如果想要实现JS调用OC方法,除了拦截URL之外,还有一种简单的方式。那就是利用WKWebView的新特性MessageHandler来实现JS调用原生方法。 Mess...
    • binglan520
    • binglan520
    • 2017年03月01日 10:05
    • 156

    IOS多线程

    IOS多线程
    • y550918116j
    • y550918116j
    • 2015年09月23日 16:39
    • 540

    WKWebView与js通信

    转载自:http://www.cokco.cn/thread-13469-1-1.html WKWebView (iOS 8 + ) iOS 8 引入WKWebView,?WKWebVie...
    • reylen
    • reylen
    • 2015年06月10日 18:58
    • 17622

    WKWebView新特性及JS交互

    声明本博文原始地址在: http://mp.weixin.qq.com/s?__biz=MzIzMzA4NjA5Mw==&mid=400327803&idx=1&sn=2a09fa94dd605a9...
    • woaifen3344
    • woaifen3344
    • 2015年10月27日 18:33
    • 28132

    UIGestureRecognizer(进阶)

    手势识别基础(Objective-C)在上一篇博文,我们已经讲解了关于手势识别的基础知识。这篇博文我们会实现下列需求。 使用UIPinchGestureRecognizer缩放View; 使用UIRo...
    • y550918116j
    • y550918116j
    • 2015年11月08日 18:37
    • 382

    iOS下OC与JS的交互(WKWebview-MessageHandler实现)

    在开发过程中,iOS 中实现加载 web 页面主要有两种控件,UIWebView和WKWebview,两种控件对应具体的实现方法不同。...
    • u013134119
    • u013134119
    • 2016年12月09日 15:02
    • 232

    WKWebView js交互方法以及 内存泄漏

    WKWebView 相对webView来说加载网页来说速度不在一个层级,占用内存也比较少,在这里咱们不谈WK的使用问题,咱们来聊聊交互问题以及内存泄漏问题 ? ? ?交互...
    • jx_zls
    • jx_zls
    • 2017年02月26日 22:56
    • 427

    WKWebView的基本使用,与网页h5交互,解决self不释放的问题

    iOS8以后,苹果推出了新框架Wekkit,提供了替换UIWebView的组件WKWebView。各种UIWebView的问题没有了,速度更快了,占用内存少了,一句话,WKWebView是App内部加...
    • AckyiOSDeveloper
    • AckyiOSDeveloper
    • 2016年03月29日 21:13
    • 2508
    内容举报
    返回顶部
    收藏助手
    不良信息举报
    您举报文章:WKWebView中MessageHandler的内存泄漏问题解决过程
    举报原因:
    原因补充:

    (最多只允许输入30个字)