2012-08-05 20 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]]]; 

たびに利用可能な新しいコンテンツがあり、私は、Webビューをリフレッシュするために再びloadHTMLStringを実行します。同じWebビュー、同じコントローラ、すべて同じものを再利用します。

インスツルメンツすべてのリークしたオブジェクトは、様々なサイズおよびそれらのどれの一般的なブロックされた非常に奇妙なパターンがそれに接続されているすべての情報がある示していますたびloadHTMLStringノー責任ライブラリ、ノー責任フレームなどが実行されます、新しいリークが追加されます。

S.Oにはいくつかのスレッドがあるようです。約UIWebViewメモリが漏れています。見つけたすべての提案を試してみました(例えば、NSURLCacheをゼロに設定する、またはリセットする、新しいデータなどがあるたびに新しいUIWebViewを割り当てようとしましたが)何も助けてくれませんでした。

これまでの調査では、1つの明確な結果が得られました。リークは、ビューにロードするHTMLにJavascriptが含まれている場合にのみ存在するようです。上記のhtml文字列に気付くと、それはいくつかのコンポーネントで構成されています。私はこれを削除した場合

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

、漏れがない:一つは、単に返す関数である[self scripts]です。しかし、私がHTMLに<script>タグを追加するとすぐにリークが表示されます。

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

ので、質問:私は単に(としてこれに、または任意の他のjsファイル)jqueryのファイルを含める場合は彼らも表示されている誰もがここで何が起こっているかについての考え?私のHTMLに明らかにJavascriptファイルを含めると、UIWebViewのリークメモリが作成されます。

私は同じUIWebViewオブジェクトを再利用するか、私は新しいものをインスタンス化するとき、私は、コンテンツを持っているたびに、JavaScriptファイルがloadHTMLStringたリードによって処理される方法で何かがなければならないことを考えるように私をリードするとき漏れが両方表示されているという事実漏れに

これはどのように修正できるか知っていますか?

enter image description here

+0

これはUIWebViewのバグである可能性があります。 http://blog.techno-barje.fr/post/2010/10/04/UIWebView-secrets-part1-memory-leaks-on-xmlhttprequest/ –

+0

@ H2CO3:ありがとう、私もそれを試みた...改善はありません。 .. – sergio

+0

私たちはiOSによって保存されていると思います。8.この回答をWKWebView http://stackoverflow.com/questions/16514230/massive-memory-leak-in-ios-uiwebviewでチェックアウトしてください –

答えて

11

私は最終的に何が起こっているかで、私は共有したいすべての問題を回避する上でいくつかの手がかりを見つけました。

JavaScriptビューのリロード時に、JavaScriptファイルが単純にインクルードされてメモリリークが発生していることを確認できます。私はさらに、HTMLコンテンツを含むファイルを構築し、それをUIWebViewからloadRequestにロードし、reloadでリロードしました。漏れは常にそこにあった。私はそれのためのレーダーを掲示します。

私が保存したものは、innerHTMLを使用してウェブビューのコンテンツを更新していました。代わりにreloadまたはloadHTMLStringに頼るので、私は空のボディと私のWebビューを初期化し(私が意味する、headセクションでは、すべての必要なJS/CSSファイルを含め、そこにあった)、それはdocument.body.innerHTML設定更新:setBodyと

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

このように定義された:

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

私は2つの利点が得られ:Web表示の更新があり(これは一方で、全体的に完全に望ましくないDOMを更新しないの効果で)本当に速くなった、とインストゥルメントの下でアプリを実行していたメモリリークはありませんでした。欠点は、アプリがうまく動作していたいくつかの条件を微調整しなければならないということでした。具体的に:あなたはDOMの準備ができたときに、そのコンテンツの最初の更新を同期化する必要がありますので、(たとえ空の本文ページを含む)のWebビューをロード

  1. は、多くのことを取ります。

  2. webViewDidFinishLoadingは信頼できないようです:document.readyStatecompleteになる前に実行されます。

  3. document.documentElement.height、ページの高さを取得する公式の方法は、あまりにも、信頼性がないようです。この問題を回避するには、body一部の「計算されたスタイルを」取得し、そのheight値を読み取るされます。

希望すると、自分のウェブビューにメモリがリークしていることが判明した他の人に役立ちます。

関連する問題