2012-08-05 49 views
10

我正在嘗試修復一些我的UIWebView導致的泄漏,但找不到它們的原點,也沒有解決方法。我要做的就是充分利用網絡的一些內容通過網絡請求,然後組裝我的HTML並加載它在飛行:使用UIWebView和Javascript的內存泄漏

NSString* body = <some HTML>; 
NSString* html = [NSString stringWithFormat:kHTMLTemplate, [self scripts], [self styles], body]; 
[_webView loadHTMLString:html 
       baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]]; 

每次有新的內容可用,我執行loadHTMLString再度刷新Web視圖。我重用相同的Web視圖,相同的控制器,相同的一切。

儀器顯示出非常奇怪圖案,其中所有泄漏對象是各種尺寸和它們都不已連接到它的任何信息的通用塊:沒有負責庫,沒有負責幀等每次執行loadHTMLString ,新的泄漏被添加。

S.O.似乎有幾個線程。約UIWebView泄漏內存。我嘗試了所有我發現的建議(例如,將NSURLCache設置爲零,或重置它;我嘗試釋放現有的UIWebView,並在每次有新數據時分配一個新的數據等),但沒有任何幫助。

我的調查到現在爲止導致了一個明顯的結果:似乎只有當我加載到視圖中的HTML包含一些Javascript時纔會出現泄漏。如果您注意到上面的html字符串,它由幾個組件組成;一個是[self scripts]它是簡單地返回一個功能:

return @"<script type='text/javascript' src='jquery-1.4.4.min.js'></script>" 
     "<script type='text/javascript' src='jmy.js'></script>"; 

如果我刪除此,無泄漏的存在。但是,只要我在我的HTML中添加<script>標記,就會出現泄漏。他們甚至會出現,如果我只是包括jQuery的文件(或任何其他JS文件,對此):

return @"<script type='text/javascript' src='jquery-1.4.4.min.js'></script>"; 

所以,問題:有沒有人對這裏發生了什麼想法?很明顯,在我的HTML中包含一個Javascript文件會導致內存泄漏。

當我重複使用同一個對象時出現泄漏或者每當我有內容時實例化一個新對象這一事實導致我認爲必須有某種方式使用JavaScript文件處理loadHTMLString,泄漏。

有誰知道如何解決這個問題?

enter image description here

+0

這可能是UIWebView中的一個錯誤。 http://blog.techno-barje.fr/post/2010/10/04/UIWebView-secrets-part1-memory-leaks-on-xmlhttprequest/ – 2012-08-05 11:05:49

+0

@ H2CO3:謝謝,我也試過...沒有改進。 .. – sergio 2012-08-05 11:11:36

+0

認爲我們保存了iOS 8.檢查這個答案在WKWebView http://stackoverflow.com/questions/16514230/massive-memory-leak-in-ios-uiwebview – 2015-02-18 15:03:06

回答

11

我終於找到了一些線索,在發生什麼事,首先,我想與大家分享一個解決方法。

我可以確認一些JavaScript文件的簡單包含導致重新加載Web視圖時發生內存泄漏。我甚至嘗試用HTML內容構建文件,然後將其加載到UIWebViewloadRequest,並通過reload重新加載;泄漏總是在那裏。我會爲此發佈一個雷達。

保存我的東西是使用innerHTML來更新Web視圖的內容。而不是依靠reloadloadHTMLString的,我初始化我的網絡視圖與空體(我的意思是,head部分在那裏,包括所有必需的JS/CSS文件),然後更新其設置document.body.innerHTML

body = [body stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; 
[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"setBody(\"%@\");", body]]; 

與setBody這樣定義的:

var setBody = function(body) { 
    document.body.innerHTML = body; 
} 

我獲得的兩個好處:web視圖更新變得非常快(這不是更新DOM,這在另一方面是不完全理想的總體上的效果),並有在Instruments下運行應用程序時沒有內存泄漏。缺點是我不得不調整一些應用運行正常的條件;具體做法是:

  1. 加載Web視圖(即使是空的正文頁面)走了很多,所以你要其內容當DOM準備的第一次更新同步;

  2. webViewDidFinishLoading似乎不可靠:它在document.readyState變成complete之前執行;

  3. document.documentElement.height,檢索頁面高度的正式方式似乎並不可靠,太:解決方法是越來越body部分的「計算樣式」,並閱讀其height價值。

希望這可以幫助別人誰發現他的網絡瀏覽量泄漏內存。