前言
本文主要解决WKWebView在通过WKUserContentController添MessageHandler方法用于JS调用Native导致ViewController内存泄露,无法正常释放。
ViewController没有调用dealloc可能的原因
在调用WKWebView时,ViewController没有调用- (void)dealloc
方法。之后检查了ViewController中所有使用到self
的地方,发现WKUserContentController的下面这个方法有使用到self
关键字
-(void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
config.userContentController = [[WKUserContentController alloc] init];
[config.userContentController addScriptMessageHandler:self name:@"finishMethod"];
所以Google了一下搜到的结果该方法,确实是由于该方法引起ViewController内存泄漏。
解决方案
WeakScriptMessageDelegate
@interface WebJsDelegate:NSObject <WKScriptMessageHandler>
@property(nonatomic,weak)id<WKScriptMessageHandler> target;
- (instancetype)initWithScriptTarget:(id<WKScriptMessageHandler>)target;
@end
@implementation WebJsDelegate
- (instancetype)initWithScriptTarget:(id<WKScriptMessageHandler>)target{
if(self=[super init]){
self.target = target;
}
return self;
}
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
if([self.target respondsToSelector:@selector(userContentController:didReceiveScriptMessage:)]){
[self.target userContentController:userContentController didReceiveScriptMessage:message];
}
}
@end
调用
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
config.userContentController = [[WKUserContentController alloc] init];
[config.userContentController addScriptMessageHandler:[[WebJsDelegate alloc]initWithScriptTarget:self] name:@"finishMethod"];
- (void)dealloc {
[self.config.userContentController removeScriptMessageHandlerForName:@"finishMethod"];
}