本文主要解決WKWebView在通過WKUserContentController添加MessageHandler方法用于JS調(diào)用Native導(dǎo)致ViewController內(nèi)存泄露,無法正常釋放。
1.ViewController沒有調(diào)用dealloc可能的原因
在使用WKWebView時(shí)肛响,ViewController在該釋放的時(shí)候沒有釋放(沒有調(diào)用- (void)dealloc方法)厚柳。參考了這篇文章檢查了ViewController中的NSTimer砸泛、delegate并將所有block中的self更換為weakSelf凯砍,結(jié)果仍然沒有調(diào)用dealloc方法愤炸。
之后檢查了ViewController中所有使用到self的地方蟆肆,發(fā)現(xiàn)WKUserContentController的下面這個(gè)方法有使用到self:
App注冊(cè)方法用于JS調(diào)用
- (void)addScriptMessageHandler:(id )scriptMessageHandler name:(NSString *)name
WKWebViewConfiguration *wkConfig = [[WKWebViewConfiguration alloc] init];
wkConfig.userContentController = [[WKUserContentController alloc] init];
[wkConfig.userContentController addScriptMessageHandler:self name:@"Native"];
所以Google了一下該方法是否會(huì)引起ViewController不調(diào)用dealloc方法矾睦。確實(shí)是由于該方法引起ViewController內(nèi)存泄漏。
2. 解決方案
(1)WeakScriptMessageDelegate
可以創(chuàng)建一個(gè)新的類WeakScriptMessageDelegate炎功,也可以將@interface-@end寫在ViewController.h中枚冗,@implementation-@end寫在ViewController.m中。
@interface WeakScriptMessageDelegate : NSObject
@property (nonatomic, weak) id scriptDelegate;
- (instancetype)initWithDelegate:(id)scriptDelegate;
@end
@implementation WeakScriptMessageDelegate
- (instancetype)initWithDelegate:(id)scriptDelegate {
? ? self = [super init];
? ? if (self) {
? ? ? ? _scriptDelegate = scriptDelegate;
? ? }
? ? return self;
}
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
? ? [self.scriptDelegate userContentController:userContentController didReceiveScriptMessage:message];
}
@end
(2)使用
添加了下面這行代碼之后ViewController就會(huì)調(diào)用dealloc方法蛇损,此時(shí)ViewController已經(jīng)正常釋放赁温。但是WeakScriptMessageDelegate沒有釋放,需要在dealloc中將WeakScriptMessageDelegate釋放掉淤齐。
WKWebViewConfiguration *wkConfig = [[WKWebViewConfiguration alloc] init];
wkConfig.userContentController = [[WKUserContentController alloc] init];
[wkConfig.userContentController addScriptMessageHandler:[[WeakScriptMessageDelegate alloc] initWithDelegate:self] name:@"Native"];
(3)釋放WeakScriptMessageDelegate
- (void)dealloc {
? ? [self.wkConfig.userContentController removeScriptMessageHandlerForName:@"Native"];
}
作者:Jixin
鏈接:http://www.reibang.com/p/1f2dc3d3090a
來源:簡(jiǎn)書
著作權(quán)歸作者所有股囊。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處更啄。