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

每次有新的内容可用,我执行loadHTMLString再度刷新Web视图。我重用相同的Web视图,相同的控制器,相同的一切。

仪器显示出非常奇怪图案,其中所有泄漏对象是各种尺寸和它们都不已连接到它的任何信息的通用块:没有负责库,没有负责帧等每次执行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>"; 

如果我删除此,无泄漏的存在。但是,只要我在我的HTML中添加<script>标记,就会出现泄漏。他们甚至会出现,如果我只是包括jQuery的文件(或任何其他JS文件,对此):

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

所以,问题:有没有人对这里发生了什么想法?很明显,在我的HTML中包含一个Javascript文件会导致内存泄漏。

当我重复使用同一个对象时出现泄漏或者每当我有内容时实例化一个新对象这一事实导致我认为必须有某种方式使用JavaScript文件处理loadHTMLString,泄漏。

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

enter image description here

+0

这可能是UIWebView中的一个错误。 http://blog.techno-barje.fr/post/2010/10/04/UIWebView-secrets-part1-memory-leaks-on-xmlhttprequest/ – 2012-08-05 11:05:49

+0

@ H2CO3:谢谢,我也试过...没有改进。 .. – sergio 2012-08-05 11:11:36

+0

认为我们保存了iOS 8.检查这个答案在WKWebView http://stackoverflow.com/questions/16514230/massive-memory-leak-in-ios-uiwebview – 2015-02-18 15:03:06

回答

11

我终于找到了一些线索,在发生什么事,首先,我想与大家分享一个解决方法。

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

保存我的东西是使用innerHTML来更新Web视图的内容。而不是依靠reloadloadHTMLString的,我初始化我的网络视图与空体(我的意思是,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价值。

希望这可以帮助别人谁发现他的网络浏览量泄漏内存。