美文网首页
iOS WKScriptMessageHandler循环引用解决

iOS WKScriptMessageHandler循环引用解决

作者: 某非著名程序员 | 来源:发表于2019-11-01 07:13 被阅读0次

    问题:在使用WKWebView时与h5交互时,监听了h5的事件,让h5可以调用OC方法。退出页面后发现WKWebView没有被释放。

    CMWebWeakScriptMessageDelegate * scriptMsgDelegate = [[CMWebWeakScriptMessageDelegate alloc] initWithDelegate:self];
    WKUserContentController *userContentController = [[WKUserContentController alloc] init];
    [userContentController addScriptMessageHandler:scriptMsgDelegate name:WEBVIEW_CLOSE_ACTION];
    

    1.循环引用的原因

    循环引用

    CMWKWebView持有了WKWebViewConfiguration,而WKWebViewConfiguration持有了WKUserContentController。在添加事件时addScriptMessageHandler,WKUserContentController有强持有了CMWKWebView。导致了循环引用。

    2.经典的解决方案:

    对于系统的这种循环引用,我们只要断开其中一环即可。

    解决方案

    增加一个中间类去弱引用CMWKWebView,断开环即可。CMWebWeakScriptMessageDelegate的代码:

    #import <Foundation/Foundation.h>
    #import <WebKit/WebKit.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface CMWebWeakScriptMessageDelegate : NSObject<WKScriptMessageHandler>
    @property (nonatomic, weak) id<WKScriptMessageHandler> scriptDelegate;
    - (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate;
    @end
    
    NS_ASSUME_NONNULL_END
    
    #import "CMWebWeakScriptMessageDelegate.h"
    
    @implementation CMWebWeakScriptMessageDelegate
    
    - (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
    

    总结:
    1.NSTimer循环引用大同小异,解决方案可参考:如何优雅的解决NSTimer释放问题
    2.有任何问题欢迎留言交流

    相关文章

      网友评论

          本文标题:iOS WKScriptMessageHandler循环引用解决

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