UIWebView 的祕密

1、UIWebView 的祕密-第一部分 Xmlhttprequest上的內存泄漏

原文地址:UIWebView Secrets - Part1 - Memory Leaks on Xmlhttprequest

我的第一個博客主要揭示使用 UIWebView 時出現的大的內存泄漏。UIWebViewiPhone 上唯一展示 HTML 的控件。UIWebView 有很多不同的問題,我來說一下最大的問題點。實際上,所有的 XMLHttpRequests 使用 javascript 代碼是完全泄漏的!我的意思是當你請求了檢索100ko(knockoutjs 簡稱 ko)的數據時 ,你的內存使用量便會增長到100ko!這個bug並不總是活躍,但是大多數會這樣,事實上,簡單的打開一個簡單的鏈接就會觸發 UIWebView ,比如點擊https://github.com這個鏈接。

但是當我們執行 simple test application 這個項目時來看看它的內存使用圖:

1.建立 UIWebView 對象

2.加載本地的 HTML 測試文件

3.運行項目,執行3次 XMLHttpRequest 請求, 注意每個請求後是如何釋放三倍內存!

4.引發泄漏原因是通過打開一個頁面,該頁面重定向回我們的測試文件

5.執行相同的3次 XMLHttpRequest 請求,看看有多少內存使用和完全泄露

6.我們用

 
[webview stringByEvaluatingJavaScriptFromString:@"document.body.innerHTML='';"];

來清理 HTML (當我們有很多DOM對象,有時釋放會一些內存)

7.釋放UIWebView(幾乎沒有內存釋放, 在下一篇文章會分析)

所以,綜上所述,通常情況下,當你在 UIWebView 執行這個Javascript :

 
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        xmlhttp.onreadystatechange = null;
        onSuccess(xmlhttp);
        xmlhttp.abort();
    }
};
xmlhttp.open("GET", "http://your.domain/your.request/...", true);
xmlhttp.send(); 

你將佔用並泄漏一個大量的內存!

但有一個hack來解決這個問題:當你打開一個鏈接時修復它。事實上,這導致泄漏是應用程序設置 的WebKitCacheModelPreferenceKey 屬性。當你使用 UIWebView 打開一個鏈接,這個屬性會自動設置爲“1”的值。那麼,解決方案是每次你打開一個鏈接後將改值設置回0。你可以很容易地通過在 UIWebView 的 代理UIWebViewDelegate 添加如下代碼:

 
- (void)webViewDidFinishLoad:(UIWebView *)webView {
    [[NSUserDefaults standardUserDefaults] setInteger:0
                                         forKey:@"WebKitCacheModelPreferenceKey"];
}

修改之後你的程序將減少因爲低內存而導致 程序crash。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章