我们平时开发的时候如果需要跟H5交互的话,都会写一个wkwebview的专门的页面,所有的网页视图都会往这个里面跳转,也避免不了做交互,但是大家测试过你的网页视图所在的控制器,pop退出之后真正销毁了吗?我今天遇到了这个问题,
wkwebview内存泄露
我们一般交互的时候都是如下步骤简单回顾一下
- 首先添加方法
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
[config.userContentController addScriptMessageHandler:self name:@"与后台约定的方法名"];
- 然后实现代理
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
//message.body 可以打印JS端给你传过来的数据,可以根据数据去执行相应的方法
}
- 然后dealloc方法里或者viewWillDisappear方法里面移除方法
然后我们的dealloc方法就不会再调用了,当你退出当前控制器的时候会发现当前控制器没有被销毁也就是说不走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方法就调用,控制器正常销毁了,我这里说的是其中一个原因,有时候还会有别的原因,欢迎小伙伴们在评论区留言
完美收工
网友评论