WKWebView与js交互中产生的内存泄漏

Posted WidgetBox

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WKWebView与js交互中产生的内存泄漏相关的知识,希望对你有一定的参考价值。

最近开发中突然发现富文本帖子详情内存没有释放掉,找了好久问题都没找到,终于今天发现了问题,先上一点代码片段

WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
configuration.userContentController = [WKUserContentController new];

    [configuration.userContentController addScriptMessageHandler:self name:@"jumpWeiboPostimage"];
    
    WKPreferences *preferences = [WKPreferences new];
    preferences.javascriptCanOpenWindowsAutomatically = NO;
    preferences.javaScriptEnabled = YES;
    configuration.preferences = preferences;
    
    WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectMake(WebViewX, 0, self.view.width - WebViewX * 2, 1) configuration:configuration];
    webView.scrollView.bounces = NO;
    webView.scrollView.scrollEnabled = NO;
    webView.UIDelegate = self;
    webView.navigationDelegate = self;
    [self.headerView addSubview:webView];

以上片段全部调用的系统方法,看似生蓄无害其实暗藏杀机,谁也想不到竟然是这里给我搞了好多天

问题出自 addScriptMessageHandler: name: 这个方法,之一这里传入的是self即这个类的实例,以下出自自己的猜测:configuration拥有这个类实例而这个类拥有webView,webView拥有configuration从而导致循环引用,当然了大前提是configuration对这个类是强引用,如果是弱引用那就不应该出现循环引用的问题

所以第一种方法可以再推出这个页面的时候调用 removeScriptMessagehandlerForname: 手动注销添加的方法从而达到释放vc的效果。

既然在调用 addScriptMessageHandler: name: 时传入该类的实例导致释放不掉那么可以单独定义一个类从而传入这个类来过渡一下

@interface WeakScriptMessageDelegate : NSObject<WKScriptMessageHandler>

@property (nonatomic, weak) id<WKScriptMessageHandler> scriptDelegate;

- (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate;

@end


@implementation WeakScriptMessageDelegate

- (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

此时在初始化webView注册配置时就将修改为

[configuration.userContentController addScriptMessageHandler:[[WeakScriptMessageDelegate alloc] initWithDelegate:self] name:@"jumpWeiboPostimage"];

这是你会发现vc的dealloc方法会调用了,但是存在一个问题就是刚才的那个过渡类没有释放掉,此时在dealloc方法中将webView注册监听的方法移除掉即可

[self.configuration.userContentController removeScriptMessageHandlerForName:@"jumpWeiboPostimage"];

 

by:初光夫

以上是关于WKWebView与js交互中产生的内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

iOS WKWebView JS 与 原生交互小结

Java内存泄漏问题

Android OOM之内存泄漏详解

Android 常见内存泄漏的解决方式

常见的内存泄漏原因及解决方法

利用WKWebView实现js与OC交互注意事项