UIWebView 和 Javascript 的内存泄漏

2024-04-15

我正在尝试修复我的一系列漏洞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再次刷新网页视图。我重复使用相同的网络视图、相同的控制器、相同的一切。

仪器显示出一种非常奇怪的模式,其中所有泄漏的对象都是各种大小的通用块,并且none其中有任何附加信息:没有负责任的图书馆,没有负责任的框架等。每次loadHTMLString执行后,会添加新的泄漏。

S.O. 中似乎有多个线程。关于UIWebView内存泄漏。我已经尝试了我发现的所有建议(例如,设置NSURLCache归零,或重置;我尝试释放现有的 UIWebView 并在每次有新数据时分配一个新的 UIWebView 等),但没有任何帮助。

到目前为止,我的调查得出了一个明确的结果:似乎只有当我加载到视图中的 HTML 包含一些 Javascript 时才会出现泄漏。如果您注意到html上面的string,它是由几个组件组成的;一个是[self scripts]这是一个简单返回的函数:

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

如果我把它去掉,就不会有泄漏。但是一旦我添加一个,泄漏就会出现<script>标记到我的 HTML。如果我只是包含 jquery 文件(或任何其他 js 文件,就此而言),它们甚至会出现:

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

那么问题来了:有人知道这里发生了什么吗?显然,将 Javascript 文件包含到我的 HTML 中将使UIWebView泄漏内存。

事实上,当我重复使用相同的产品时,都会出现泄漏UIWebView对象或者当我每次有内容时实例化一个新对象时,都会让我认为 javascript 文件的处理方式一定存在某种问题loadHTMLString这会导致泄漏。

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


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

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

拯救我的是使用innerHTML更新 Web 视图的内容。而不是依靠reload or loadHTMLString,我用一个空的主体初始化了我的网络视图(我的意思是,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 value.

希望这可以帮助其他发现其网络视图正在泄漏内存的人。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UIWebView 和 Javascript 的内存泄漏 的相关文章

随机推荐