1. 程式人生 > >iOS 添加WKWebView導致控制器無法釋放的問題

iOS 添加WKWebView導致控制器無法釋放的問題

tde conf dealloc instance receives nonatomic pro 最終 ace

在WkWebView與JavaScript交互中,經常會在原生中註入MessageHandler,app中註入MessageHandler的方法

    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    config.userContentController = [WKUserContentController new];
    //註入handler
    [config.userContentController addScriptMessageHandler:self name:@"HandlerName"];

這裏我們發現在向JS中註入handler的時候強引用了self,最終導致內存泄漏

解決方法 添加一個新類 WeakScriptMessageDelegate

@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

使用 添加了下面這行代碼之後ViewController就會調用dealloc方法,此時ViewController已經正常釋放。但是WeakScriptMessageDelegate沒有釋放,需要在dealloc中將WeakScriptMessageDelegate釋放掉。

    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    config.userContentController = [WKUserContentController new];
    //註入handler
    [config.userContentController addScriptMessageHandler:[[WeakScriptMessageDelegate alloc] initWithDelegate:self] name:@"HandlerName"];

釋放WeakScriptMessageDelegate 在dealloc方法中實現

    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"HandlerName"];

iOS 添加WKWebView導致控制器無法釋放的問題