往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:@"與后臺約定的方法名"];
}