实际内存不断增加 - 从视图中移除子视图 - iOS(ARC)

4
我有一个iPad应用程序,在第一代iPad上崩溃,因为它的内存不足。
在应用程序中,我有一个主视图,添加了约20个自定义类别的UIScrollView(每个都包含一个UIImageView和UIImage)。当用户移动到下一页时,我会从父视图中删除所有这些子视图,然后将20个新的UIScrollViews添加到同一个视图中。
如果我使用分配和内存泄漏来测试应用程序,一切正常-当用户向左或向右滚动时,分配的内存保持在大约2MB左右。
然而,如果我查看活动监视器中的实际内存使用情况,就会发现每当用户移动到新页面时,实际内存就会增加约20MB。最终,在浏览几个新页面后,该应用程序的大小达到150+ MB并崩溃。
请问有人能够建议可能导致这种行为的原因以及如何进一步排除故障?
关于应用程序结构的更多信息:
在视图加载完成时,使用initWithContentsOfFile将图像加载到NSMutableArray中。
1个回答

1

你不应该将这些图片存储在数组中进行维护。图片会占用你有限的内存空间,使其不成比例地消耗内存。有几种方法可以解决:

  1. 如果你想保持简单,那就不要将图像存储在任何地方。通过使用initWithContentsOfFile加载图像来加载 UIImageViewimage属性即可。

  2. 如果出于性能原因需要一些RAM缓存,可以使用imageNamed而非initWithContentsOfFile。当应用程序接收到内存警告时,缓存将自动清除。

  3. 我倾向于使用initWithContentsOfFile,但会手动缓存到自己的NSCache中(类似于一个NSDictionary,但是你可以设置一个countLimit以确定它应该保存多少个图像)。

顺便提一下,您没有描述“用户转到下一页”时技术上会发生什么。如果您只是刷新现有视图控制器上的现有控件,则一切都很正常(一旦解决了我上面讨论的NSMutableArray问题)。如果您正在推送/呈现到另一个视图控制器或滚动控件超出屏幕但忽略从其父视图中删除旧控件,则这也会导致问题。您可能需要澄清您在那里做什么。
总之,您只需要确保在从一页转到另一页时,不要维护对任何旧图像或控件的强引用。

这一切都发生在同一个UIView中。对象被添加到视图中,然后被移除,接着新的对象(在这种情况下是自定义UIScrollView)被添加。我仍然不清楚我的最初的问题 - 为什么真实的内存只在将新对象添加到视图中时增加(通过self.view addSubview x)?对象被放置在viewDidLoad方法中的数组中,此时真实内存不会增加(它很低并且保持不变)。 - GuybrushThreepwood
@Ohnomycoco 在这种情况下,我们可能需要查看一些源代码来诊断问题。但显然你在转到下一页时添加了一些东西。仅凭你目前分享的内容是不可能进行诊断的。 - Rob
@Ohnomycoco 你也可以使用Allocations工具(如此处所示:https://dev59.com/sWYq5IYBdhLWcg3w5kpm#14105056)来识别你的分配跳跃,高亮图表部分,并且它将精确地显示出是什么导致了内存消耗。 - Rob
谢谢。看起来图像直到放置在屏幕上才真正加载。从应用程序的角度来看,当图像出现在屏幕上时,内存不会增加,但从iPad实际内存的角度来看,当图像实际放置在屏幕上时,使用的内存明显增加。 - GuybrushThreepwood

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接