我們平時開發(fā)的時候如果需要跟H5交互的話,都會寫一個wkwebview的專門的頁面,所有的網頁視圖都會往這個里面跳轉,也避免不了做交互,但是大家測試過你的網頁視圖所在的控制器,pop退出之后真正銷毀了嗎?我今天遇到了這個問題,
wkwebview內存泄露
我們一般交互的時候都是如下步驟簡單回顧一下
- 首先添加方法
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
[config.userContentController addScriptMessageHandler:self name:@"與后臺約定的方法名"];
- 然后實現(xiàn)代理
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
//message.body 可以打印JS端給你傳過來的數(shù)據(jù),可以根據(jù)數(shù)據(jù)去執(zhí)行相應的方法
}
- 然后dealloc方法里或者viewWillDisappear方法里面移除方法
然后我們的dealloc方法就不會再調用了,當你退出當前控制器的時候會發(fā)現(xiàn)當前控制器沒有被銷毀也就是說不走dealloc方法,這是因為在向JS中注入handler的時候強引用了self,最終導致內存泄漏,
解決:
- 我們可以把self換掉,就是說用其他換掉self,這里面就要新建一個類
在.h里面是這樣的
#import <WebKit/WebKit.h>
@interface SHWeakScriptMessageDelegate : NSObject<WKScriptMessageHandler>
@property (nonatomic,weak)id<WKScriptMessageHandler> scriptDelegate;
- (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate;
@end
在.m里面是這樣的
#import "SHWeakScriptMessageDelegate.h"
@implementation SHWeakScriptMessageDelegate
- (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
使用方法
- 修改前
[configuration.userContentController addScriptMessageHandler:self name:@"XXXXXXXXX"];
- 修改后
[configuration.userContentController addScriptMessageHandler:[[SHWeakScriptMessageDelegate alloc] initWithDelegate:self] name:@"XXXXXXXXX"];
然后我們的dealloc方法就調用,控制器正常銷毀了,我這里說的是其中一個原因,有時候還會有別的原因,歡迎小伙伴們在評論區(qū)留言
完美收工