iOS WKScriptMessageHandler循环引用解决

2019-11-01  本文已影响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.有任何问题欢迎留言交流

上一篇下一篇

猜你喜欢

热点阅读