天天看點

wkwebview 的記憶體洩漏問題

昨天寫好的一個功能是有關wkwebview的。本身根據我的了解,wkwebview相比于uiwebview來說有了很好的優化,具體的好處這裡我就不說了,我說一下我這裡遇到的問題。

我們的項目中要用到JS調用OC和OC調用JS,

這裡要用到 WKUserContentController

WKWebViewConfiguration * configura = [[WKWebViewConfiguration alloc] init];
    WKUserContentController * userCont = [[WKUserContentController alloc] init];
    configura.userContentController = userCont;
           

使用WKUserContentController時要注意有一個記憶體崩潰的情況,要記得及時把添加的JS的方法名移除。@"openUrl"類似于這樣,全是跟H5商量好的方法名

代碼如下

- (void)AddJSInvokingOCFunctionList:(WKWebView *)wkweb viewController:(UIViewController<WKScriptMessageHandler> *)viewController{
    [wkweb.configuration.userContentController addScriptMessageHandler:viewController name:@"jsToOc"];
    [wkweb.configuration.userContentController addScriptMessageHandler:viewController name:@"openUrl"];
    [wkweb.configuration.userContentController addScriptMessageHandler:viewController name:@"callFunction"];
    [wkweb.configuration.userContentController addScriptMessageHandler:viewController name:@"xlShopShareToPY"];
}
           

添加之後記得移除

- (void)removewJSInvokingOCFunctionList:(WKWebView *)wkweb{
    [wkweb.configuration.userContentController removeScriptMessageHandlerForName:@"jsToOc"];
    [wkweb.configuration.userContentController removeScriptMessageHandlerForName:@"openUrl"];
    [wkweb.configuration.userContentController removeScriptMessageHandlerForName:@"xlShopShareToPY"];
 
}
           

我的webview是寫在viewcontroller裡面的,那麼這裡如何判斷是否還存在記憶體洩漏呢,除了使用podfiles進行動态記憶體分析之外,還可以根據是否執行了delloc方法來判斷。經過push和present得到的controller,在back回來之後,沒有記憶體洩漏的話,必然會執行delloc方法。

在我添加了這些移除的方法之後,我發現還是沒有執行delloc方法,那是怎麼回事兒呢,我一句一句的注釋代碼,一行代碼一行代碼運作,結果發現,在使用MJRefresh這個庫的時候,産生了記憶體洩漏

錯誤代碼如下:

MJRefreshNormalHeader * header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
        [self refreshAction];
    }];
           

應該認識到是,這樣的代碼沒有任何崩潰。但是在這個block方法内使用self調用方法,就會産生記憶體洩漏的問題。

修改代碼:

__weak typeof(self) weakSelf = self;
    self.wkweb.scrollView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
        [weakSelf.wkweb reload];
    }];
           

就執行了delloc方法了

這裡我總結一下:

1、在代碼開發過程中,一定要保證每個類在你認為該釋放的時候都會執行delloc方法,這樣,不會有記憶體洩漏的情況。如果沒有執行delloc,肯定是記憶體洩露了

2、不管在什麼時候,隻要是使用block,就使用weakSelf進行弱引用話,這裡要注意__weak和__strong的差別,合理使用,千萬不要以為沒有崩潰,就沒有記憶體洩漏。

3、為了避免野指針異常,可以盡量延長對象的生命周期。