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 的内存泄漏 的相关文章

  • 如何将CIFilter应用到UIView上?

    根据Apple docs 过滤属性CALayer不支持iOS 当我使用正在申请的应用程序之一时CIFilter to UIView即 Splice Funimate 和 Artisto 的视频编辑器 Videoshow FX 这意味着我们可
  • 如何在 iOS 上固定证书的公钥

    在提高我们正在开发的 iOS 应用程序的安全性时 我们发现需要对服务器的 SSL 证书 全部或部分 进行 PIN 操作以防止中间人攻击 尽管有多种方法可以做到这一点 但当您搜索此内容时 我只找到了固定整个证书的示例 这种做法会带来一个问题
  • 无需越狱即可检测iOS9上哪个应用程序处于前台

    我正在尝试记录用户在 iOS9 上的个人应用程序使用情况 我宁愿它不会使用越狱有限的解决方案 不言自明 在越狱手机上执行此应用程序的变体应该不难 https www andyibanez com create mobilesubstrate
  • 内存调试:如何获取 Linux 用户空间/内核空间中的锁定页面信息

    有什么方法可以获取Linux用户空间 内核空间中的锁定页面 虚拟内存页面 信息 我想了解详细信息 例如 谁锁定了页面 有多少页被锁定 进程名称 谁锁定了页面 还让我了解内核空间和用户空间的内存调试技术 对于内存中的每个页面 都会为其分配标志
  • 启动深色或浅色模式的图像

    如何为深色模式和浅色模式选 择一组不同的启动图像 我有一个 LaunchImages 集 当应用程序启动时 会显示一个图像 对于浅色模式 这似乎不错 但是如果我尝试在设置为深色模式 iOS 13 的设备上打开我的应用程序 则该图像看起来很糟
  • 重叠的装载机圆

    我试图重现苹果为应用程序 活动 制作的重叠圆圈 见下图 如果您使用标准贝塞尔路径 起始 结束位置将仅在 0 到 2PI 之间产生影响 例如 如果您尝试填充 4PI 即使使用一些阴影 则无法模拟重叠加载 如何制作类似于苹果解决方案的东西来创建
  • 如何向 UIView 添加大小调整手柄?

    我试图根据用户请求在运行时动态创建视图 UIImageView 和 UITextView 然后允许用户移动它们并调整它们的大小 除了调整大小之外 我的一切都工作得很好 我尝试使用捏合手势识别器 但发现它对于我想要的东西来说太笨拙了 因此 我
  • 为 iOS 应用程序加载基于 SVG 的图像资源

    我从 thenounproject 购买了一个图标作为 SVG 图像 然后我使用一个名为的 macOS 程序Gapplin http gapplin wolfrosch com 将此 SVG 导出为 PNG 图像 它显示为 100x100
  • 如何在iOS的Delphi程序中使用IPv6协议

    我尝试在我的移动程序中使用 IPv6 协议 我的服务器位于 NAT 后面的 LAN 内 在服务器上我使用IP端口3000 我已经组织了从路由器端口 45500 到服务器端口 3000 的虚拟服务器 端口转发 在服务器上 我运行 ipconf
  • 以弯曲格式显示文本

    我正在寻找以曲线格式绘制一些文本 我使用哪个控件并不重要 UITextField UILabel or UITextView 我只想显示如图所示的文本 仍在寻找解决方案 请帮忙 查看此链接 https nodeload github com
  • NSTimer 不触发选择器

    在带有 ARC 的 ios5 0 中 在我的 rootviewcontroller 中 我调用由应用程序委托持有的安全管理器对象中的方法 在该方法中 我设置计时器如下 NSTimer timer NSTimer scheduledTimer
  • 不明白 Swift 中的闭包示例

    我正在尝试了解 swift 和闭包 我被这个例子困住了 numbers map number Int gt Int in let result 3 number return result 什么是 number Int gt Int 它是一
  • ios 在后台处理推送通知

    我想保存应用程序处于后台状态时到达的推送通知 我知道关于 void application UIApplication application didReceiveRemoteNotification NSDictionary userIn
  • 如何使用 Core Graphics 在我的触摸位置绘制一个圆圈?

    新程序员来了 我在尝试使用 Core Graphics 在触摸位置周围绘制描边弧时遇到问题 我有绘制圆圈的方法工作正常 并且我已经测试并在点击屏幕时注册触摸 但是当我尝试在点击时调用绘制圆圈的方法时 我收到错误 CG ContextBlah
  • iOS 防止计时器 UILabel 在数字变化时“晃动”

    我有一个UILabel它以以下格式显示计时器的输出MM ss SS 分 秒 厘秒 但是随着厘秒宽度的变化 它从左向右 摇动 例如 11 比 33 窄 有什么办法可以减轻这种情况吗 我尝试过将其居中 给它固定的宽度 但它们似乎没有帮助 从iO
  • AWS S3 公共对象与私有对象?

    回到 S3 我的存储桶中有图像的 URL 我将在我的应用程序中呈现这些图像 但它们被设置为私有 当我尝试单击该链接时 它显示 访问被拒绝 当我将链接的设置更改为公共时 它会通过 但是我读到公共访问并不是最安全的事情 所以这本质上是一个由两部
  • ios 导航 堆栈操作

    我在尝试从 iOS 应用程序操作导航堆栈时遇到问题 或者至少是由于这种操纵而产生的行为 我的情况 我有 3 个 ViewController 控制器a显示多个级别 控制器 b 是游戏视图 控制器 c 是某种分数 显然 我将在控制器 a 中选
  • ios - Gamekit 的 GKOctree 未找到元素

    我正在尝试使用GKOctree https developer apple com documentation gameplaykit gkoctree用于高效检索 3D 空间中的对象 然而 以下代码似乎没有按预期工作 import Gam
  • iOS 电池监控 Swift

    我已将监控设置为启用 但模拟器和设备中的电池电量仍然为 1 UIDevice currentDevice batteryMonitoringEnabled true var level UIDevice currentDevice batt
  • 设置/覆盖 UICollectionView 中单元格之间的填充

    我有一个 UICollectionView 但在获取单元格之间的填充时遇到了问题 理论上 我应该能够将屏幕除以 4 并且我可以获得包含 4 个图像的单元格大小 完美地占据屏幕宽度 但是 它选择不这样做 相反 它会创建 3 个具有巨大填充的图

随机推荐