UIWebView和Javascript的内存泄漏 [英] Memory Leaks with UIWebView and Javascript

查看:127
本文介绍了UIWebView和Javascript的内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to fix a bunch of leaks that my UIWebView is causing and cannot find their origin nor a workaround. What I do is getting some content from the web through a network request, then assemble my HTML and load it on the fly:

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

Each time there is new content available, I execute loadHTMLString again to refresh the web view. I reuse the same web view, same controller, same everything.

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

Instruments shows a very strange pattern in which all leaked objects are General-blocks of various sizes and none of them has any information attached to it: no responsible library, no responsible frame, etc. Each time loadHTMLString is executed, new leaks are added.

似乎SO中有几个线程关于 UIWebView 泄漏内存。我已经尝试了我找到的所有建议(例如,将 NSURLCache 设置为零,或重置它;我尝试发布现有的UIWebView并在每次有新数据时分配一个新的UIWebView但是没有任何帮助。

It seems that there are several threads in S.O. about UIWebView leaking memory. I have tried all suggestions I found (e.g., setting the NSURLCache to zero, or resetting it; I tried releasing the existing UIWebView and allocate a fresh one each time I have new data, etc.) but nothing has helped.

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

My investigations up to now lead to one clear outcome: it seems that the leaks are only present if the HTML I load into the view contains some Javascript. If you notice the html string above, it is made up of several components; one is [self scripts] which is a function that simply returns:

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文件),它们甚至会出现:

If I remove this, no leaks are there. But the leaks appear as soon as I add a <script> tag to my HTML. They even appear if I simply include the jquery file (or any other js file, as to this):

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

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

So, the question: has anyone an idea about what is happening here? Clearly including a Javascript file into my HTML is making the UIWebView leak memory.

泄漏事件同时出现我重复使用相同的 UIWebView 对象,或者当我每次有内容时实例化一个新对象时,让我认为javascript文件的处理方式必须是 loadHTMLString 导致泄密。

The fact that leaks appear both when I reuse the same UIWebView object or when I instantiate a new one each time I have content, leads me to think that there must be something in the way javascript files are handled by loadHTMLString which leads to the leaks.

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

Does anyone know how this could be fixed?

推荐答案

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

I finally found some clue at what is happening and above all a workaround that I would like to share.

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

I can confirm that the simple inclusion of some javascript file was causing a memory leak on reload of the web view. I even tried building a file with the HTML content, then loading it into the UIWebView through loadRequest, and reloading it through reload; the leaks were always there. I will post a radar for that.

是什么让我节省了使用 innerHTML 来更新网页视图的内容。我没有依赖重新加载 loadHTMLString ,而是用空体初始化我的网页视图(我的意思是, head 部分,包括所有必需的JS / CSS文件)然后更新它设置 document.body.innerHTML

What saved me was using innerHTML to update the content of the web view. Instead of relying on reload or loadHTMLString, I initialized my web view with an empty body (I mean, the head section was there, including all required JS/CSS files) then updated it setting document.body.innerHTML:

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

setBody定义如下:

with setBody defined like this:

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

我获得了两个好处:网页视图更新变得非常快(这是一个没有更新DOM的效果,另一方面整体上并不完全是可取的),并且在仪器下运行应用程序没有内存泄漏。缺点是我必须微调应用程序正常运行的几个条件;具体来说:

I obtained two benefits: the web view update became really fast (this is an effect of not updating the DOM, which on the other hand is not entirely desirable on the whole), and there were no memory leaks were running the app under Instruments. The drawback was that I had to fine-tune a couple of conditions where the app was running fine; specifically:


  1. 加载网页视图(即使是一个空的正文页面)需要花费很多,所以你必须同步第一个将内容更新到DOM准备好的时候;

  1. loading the web view (even with an empty body page) take a lot, so you have to synchronize the first update of its content to when the DOM is ready;

webViewDidFinishLoading 似乎不可靠:它被执行在 document.readyState 之前完成;

webViewDidFinishLoading seems not reliable: it is executed before document.readyState becomes complete;

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

document.documentElement.height, the official way of retrieving the page height seems not reliable, too: workaround is getting the "computed style" of the body part and read its height value.

希望这可以帮助那些发现他的网络视图泄露内存的人。

Hope this helps someone else who finds that his web views are leaking memory.

这篇关于UIWebView和Javascript的内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆