往WKWebView内注入JS方法时,出现内存无法释放问题
先说说wkWebView与JS交互的方法吧
WKWebViewConfiguration*config = [[WKWebViewConfigurationalloc] init];
[config.userContentController addScriptMessageHandler:selfname:@"与后台约定的方法名"];
//创建webView
WKWebView *webView = [[WKWebView alloc]initWithFrame:self.view.frame configuration:config];
wenView.navigationDelegate = self;
在上面的这个方法里面去创建一个webView,并且约定方法名称。
执行本地的方法时会调用以下代理方法
-(void)userContentController:(WKUserContentController*)userContentController didReceiveScriptMessage:(WKScriptMessage*)message{
//message.body
可以打印JS端给你传过来的数据,可以根据数据去执行相应的方法
}
你以为JS调用本地的方法就完事了吗?
错误,你会发现调用方法后,内存根本不释放。也就是dealloc方法不执行。
问题就出现在
[config.userContentController addScriptMessageHandler:self name:@"与后台约定的方法名"];
这句代码上面,准确的说是“self”的身上。
那么怎么解决呢?
解决方法一
我们可以把self换掉,就是说用其他换掉self,这里面就要新建一个类
在.h里面是这样的
#import
@interfaceXLWeakScriptMessageDelegate:NSObject
@property(nonatomic,weak)id scriptDelegate;
- (instancetype)initWithDelegate:(id)scriptDelegate;
@end
在.m里面是这样的
#import "XLWeakScriptMessageDelegate.h"
@implementationXLWeakScriptMessageDelegate
- (instancetype)initWithDelegate:(id)scriptDelegate{
self= [superinit];
if(self) {
_scriptDelegate =scriptDelegate;
}
return self;
}
- (void)userContentController:(WKUserContentController*)userContentController didReceiveScriptMessage:(WKScriptMessage*)message{
[
self.scriptDelegateuserContentController:userContentControllerdidReceiveScriptMessage:message];
}
@end
新建的类我都写在这里了,大家可以拿过去直接用。
下面说的是最重要的改动,就是把
WKWebViewConfiguration*config = [[WKWebViewConfigurationalloc] init];
[config.userContentController addScriptMessageHandler:self name:@"与后台约定的方法名"];
这里面的代码改造成
WKWebViewConfiguration*config = [[WKWebViewConfigurationalloc] init];
[config.userContentController addScriptMessageHandler:[[
XLWeakScriptMessageDelegatealloc] initWithDelegate:self] name:@"callback"];
//创建webViewWKWebView*webView = [[WKWebViewalloc] initWithFrame:self.view.frameconfiguration:config];
webView.navigationDelegate = self;
这样一来,会发现内存释放了,dealloc方法会被执行了。
解决方法二、
.在当前界面显示的时候往WKWebView中注入JS,当界面消失时移除JS方法
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.webView..configuration.userContentController addScriptMessageHandler:self name:@"与后台约定的方法名"];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillAppear:animated];
[self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"与后台约定的方法名"];
}