在WkWebView与JavaScript交互中,经常会在原生中注入JS 消息,如下:
WKUserContentController *userContentController = [[WKUserContentController alloc] init];
[userContentController addScriptMessageHandler:self name:@"handleGoMall"];
然后在WKScriptMessageHandler的回调方法中:
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
QYLog(@"message.name:%@", message.name);
QYLog(@"message.body:%@",message.body);
// 根据name做想做的操作
if ([message.name isEqualToString:@"handleGoMall"]) {//跳转购买滤芯
}
}
这样做可以达到预期效果,但是当你退出当前控制器的时候会发现当前控制器没有被销毁也就是说不走dealloc方法,这是因为在向JS中注入handler的时候强引用了self,最终导致内存泄漏,
解决方法:
创建一个新类:QYWeakScriptMessageHandlerDelegate
@interface QYWeakScriptMessageHandlerDelegate : NSObject<WKScriptMessageHandler>
@property (nonatomic, weak) id<WKScriptMessageHandler> scriptDelegate;
- (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate;
@end
@implementation QYWeakScriptMessageHandlerDelegate
- (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate {
if (self = [super init]) {
_scriptDelegate = scriptDelegate;
}
return self;
}
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
[self.scriptDelegate userContentController:userContentController didReceiveScriptMessage:message];
}
使用:
把:
[userContentController addScriptMessageHandler:self name:@"handleGoMall"];
替换成:
[userContentController addScriptMessageHandler:[[QYWeakScriptMessageHandlerDelegate alloc] initWithDelegate:self] name:@"handleGoMall"];
最后在dealloc中释放:
- (void)dealloc {
[self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"handleGoMall"];
}
这样退出当前控制器时,当前控制器就会销毁了。
网友评论