内存泄漏与UIWebView和Javascript

我正在尝试解决一些我的UIWebView导致的泄漏,无法find它们的原点,也没有解决方法。 我所做的是通过networking请求从networking获取一些内容,然后组装我的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视图。 我重复使用相同的Web视图,相同的控制器,相同的一切。

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

看来有关于UIWebView泄漏内存的几个线程。 我已经尝试了所有我发现的build议(例如,将NSURLCache设置为零,或重置它;我试图释放现有的UIWebView,并分配一个新的每次我有新的数据等),但没有任何帮助。

到目前为止,我的调查导致了一个清晰的结果:似乎只有当我加载到视图中的HTML包含一些Javascript时才会出现泄漏。 如果你注意到上面的htmlstring,它由几个组件组成; 一个是[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>"; 

所以,这个问题:有没有人知道这里发生了什么? 清楚地包括一个JavaScript文件到我的HTML是使UIWebView泄漏内存。

事实上,当我重用相同的UIWebView对象时,或者当我每次有内容时都实例化一个新的对象时,都会出现泄漏,这让我认为javascript文件必须以某种方式处理loadHTMLString ,从而导致泄漏。

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

在这里输入图像说明

我终于发现了一些线索,发生了什么,最重要的是我想分享一个解决方法。

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

什么救了我使用innerHTML来更新networking视图的内容。 而不是依靠reloadloadHTMLString ,我用一个空的身体(我的意思是, head部分在那里,包括所有必需的JS / CSS文件)初始化我的Web视图,然后更新它设置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值。

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