【问题标题】:Memory Leaks with UIWebView and JavascriptUIWebView 和 Javascript 的内存泄漏
【发布时间】:2012-08-02 15:46:47
【问题描述】:

我正在尝试修复我的UIWebView 导致的一堆泄漏,但找不到它们的来源,也找不到解决方法。我所做的是通过网络请求从网络获取一些内容,然后组装我的 HTML 并动态加载它:

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 视图、相同的控制器、相同的一切。

Instruments 显示出一种非常奇怪的模式,其中所有泄露的对象都是各种大小的通用块,并且没有它们有任何附加信息:没有负责的库、没有负责的框架等。当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>";

如果我删除它,就没有泄漏。但是,一旦我将&lt;script&gt; 标签添加到我的 HTML 中,就会出现泄漏。如果我简单地包含 jquery 文件(或任何其他 js 文件),它们甚至会出现:

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

所以,问题是:有人知道这里发生了什么吗?显然,在我的 HTML 中包含一个 Javascript 文件会导致 UIWebView 泄漏内存。

当我重用相同的 UIWebView 对象或每次我有内容时实例化一个新对象时都会出现泄漏,这让我认为 @987654337 处理 javascript 文件的方式一定有问题@ 导致泄漏。

有谁知道如何解决这个问题?

【问题讨论】:

标签: ios uiwebview memory-leaks


【解决方案1】:

我终于找到了一些关于正在发生的事情的线索,最重要的是我想分享一个解决方法。

我可以确认,一些 javascript 文件的简单包含导致重新加载 Web 视图时出现内存泄漏。我什至尝试用 HTML 内容构建一个文件,然后通过loadRequest 将其加载到UIWebView,并通过reload 重新加载它;泄漏总是存在的。我会为此发布一个雷达。

拯救我的是使用innerHTML 来更新网络视图的内容。我没有依赖reloadloadHTMLString,而是用一个空主体初始化了我的Web 视图(我的意思是,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 的效果,另一方面,整体上并不完全可取),并且在运行应用程序时没有内存泄漏在仪器下。缺点是我必须微调应用程序运行良好的几个条件。具体来说:

  1. 加载 web 视图(即使是空的正文页)需要很多时间,因此您必须将其内容的第一次更新同步到 DOM 准备好时;

  2. webViewDidFinishLoading 似乎不可靠:它在document.readyState 变为complete 之前执行;

  3. document.documentElement.height,获取页面高度的官方方法似乎也不可靠:解决方法是获取body 部分的“计算样式”并读取其height 值。

希望这可以帮助那些发现他的 web 视图正在泄漏内存的人。

【讨论】:

    猜你喜欢
    • 2015-04-08
    • 1970-01-01
    • 2013-11-13
    • 2019-04-10
    • 1970-01-01
    • 2011-09-19
    • 2010-10-13
    • 2011-04-08
    相关资源
    最近更新 更多