我有一个网络应用程序,它从 zip 文件加载图像,并连续显示它们。
zip 文件可以存储许多图像。
为了防止内存不足,管理内存,方法是在显示下一个图像之前从以前的图像中清除内存。
这是通过以下方式完成的:
- 将缓冲区设置为空。
- 撤销对象 url 并将 url 设置为null。
这种方法适用于各种操作系统,例如Windows、Linux 和 MacOS。
但在 iOS 上它失败了。
我在这里放置了一个示例来演示该问题。
在示例中,一个 zip 文件中的一组图像循环显示,以模拟一个包含许多图像的 zip 文件。
将变量doDebugMemoryLeakOn_iOS_withRevoke设置为 true,激活代码
URL.revokeObjectURL(fileInfo.url);
这会导致问题,一段时间后(在我的 iPad Pro 上大约 1100 张图像之后)。
可以通过运行程序并选择zip 文件来查看问题。
(或任何其他带有多个 jpeg 图像的 zip 文件 - 链接的 zip 文件仅包含 3 个 4032x3024 大小的图像)
在某些时候,程序失败并显示错误消息:“I/O 读取操作失败”
当在各种浏览器(例如Safari、Chrome、Firefox)中播放大约 1000 张图像后,这种情况会发生在具有各种iOS版本(iOS 15.2、iOS 14.8.1 )的各种iOS设备(例如iPad、iPhone8 )上。
它也发生在使用WKWebView的原生 iOS 应用程序中。我怀疑WKWebView浏览器引擎
可能存在问题,这是所有这些浏览器共有的。
注意:有几个地方评论了调整设置,例如GPU Process: Canvas Rendering
这在一定程度上推迟了问题,但在某些时候仍然会出现错误。
问题发生后,无法以编程方式恢复,例如通过重试读取 zip 文件条目或跳到下一个 zip 条目。
唯一的解决方案是再次选择文件。
这是否表明WKWebView中存在错误?
如何解决或解决此问题?
谢谢
编辑:
为了简化调试,我将 loading-from-zipfile 替换为 loading-from-external-url。
为了模仿创建和清理对象 url 的行为,我
- 通过 revokeObjectURL 人为地清理对象 url
- 从外部 url 获取 blob,并且
- 通过 createObjectURL 创建一个对象 url。