iOS WKWebView導致ViewController不調(diào)用dealloc方法

本文主要解決WKWebView在通過WKUserContentController添加MessageHandler方法用于JS調(diào)用Native導致ViewController內(nèi)存泄露,無法正常釋放。

1.ViewController沒有調(diào)用dealloc可能的原因

在使用WKWebView時,ViewController在該釋放的時候沒有釋放(沒有調(diào)用- (void)dealloc方法)。參考了這篇文章檢查了ViewController中的NSTimer、delegate并將所有block中的self更換為weakSelf,結果仍然沒有調(diào)用dealloc方法。

之后檢查了ViewController中所有使用到self的地方,發(fā)現(xiàn)WKUserContentController的下面這個方法有使用到self:
App注冊方法用于JS調(diào)用

- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name
WKWebViewConfiguration *wkConfig = [[WKWebViewConfiguration alloc] init];
wkConfig.userContentController = [[WKUserContentController alloc] init];
[wkConfig.userContentController addScriptMessageHandler:self name:@"Native"];

所以Google了一下該方法是否會引起ViewController不調(diào)用dealloc方法。確實是由于該方法引起ViewController內(nèi)存泄漏。
搜到的結果

2. 解決方案

(1)WeakScriptMessageDelegate

可以創(chuàng)建一個新的類WeakScriptMessageDelegate,也可以將@interface-@end寫在ViewController.h中,@implementation-@end寫在ViewController.m中。

@interface WeakScriptMessageDelegate : NSObject<WKScriptMessageHandler>

@property (nonatomic, weak) id<WKScriptMessageHandler> scriptDelegate;

- (instancetype)initWithDelegate:(id<WKScriptMessageHandler>)scriptDelegate;

@end
@implementation WeakScriptMessageDelegate

- (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

(2)使用

添加了下面這行代碼之后ViewController就會調(diào)用dealloc方法,此時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"];
}
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容