0

背景:我有一个标签栏控制器,目前包含 4 个标签。其中 3 个选项卡是导航控制器,它们显示用于查看、编辑和创建数据的表视图的层次结构。数据通常是从用户那里获取并存储在全局变量中的 NSStrings(数据需要从层次结构中的多个视图以及多个选项卡中访问)。

问题我注意到我的应用程序一启动就使用了相当多的内存(~11mb)。然而,当我滚动浏览表视图并使用导航控制器访问更多表视图并编辑一些数据时,内存使用量迅速上升到近 20mb。最糟糕的部分是弹出详细视图控制器不会导致内存使用量减少。它将徘徊在20-21mb左右,如果我重复这个过程,我的内存使用率似乎越来越高。我已经在 Leaks 中测试了我的应用程序,并且在那里解决了所有问题。我怀疑我的非活动视图控制器仍在内存中,即使它们当前没有显示。有没有办法在导航控制器的层次结构中释放不需要的视图控制器,甚至是标签栏中的非活动视图控制器?我一直在阅读 Apple 的文档,他们强烈建议在视图控制器和应用程序委托中实现didReceiveMemoryWarning:和。applicationDidReceiveMemoryWarning:我真的不知道从哪里开始使用这些方法。我可以发布哪些控制器以及如何重新创建它们?我认为我对此负责,但我想确定一下。

请注意,由于内存使用率低,我还没有让我的应用程序终止,但是足够的数据输入重复(大量视图控制器推送和弹出)将导致它缓慢爬行。

4

2 回答 2

3

如果重复查看相同的屏幕会导致内存使用率越来越高,那么您就有了泄漏。泄漏没有检测到它的事实并不意味着您没有泄漏。如果您持有不应该持有的数据,即使是垃圾收集程序也可能泄漏。

调出带有对象分配模板的仪器,看看是什么占用了你的大部分内存。看看那些不应该在内存中的东西。如果您认为您的视图控制器应该内存不足,请将其放入NSLog()-dealloc确认它们确实内存不足。

您应该didReceiveMemoryWarning在视图控制器中实现,Apple 给出了如何在Nib Objects 的内存管理中实现它的指南。至少你应该在其中实现一个日志语句,didReceiveMemoryWarning这样你就知道你是否收到了警告。但这不太可能是实际问题。未能实现此方法不会导致内存泄漏,它只会阻止您在内存不足的情况下尽可能快地释放内存。

您是否遵循 Cocoa 内存管理的第一条规则:您应该使用访问器?不要直接弄乱你的实例变量,大多数内存管理问题都会消失。

于 2009-08-05T22:04:55.210 回答
0

实际上,在 iPhone OS 3.0+ 中,UIViewController子类通常应该只实现viewDidUnload而不是didReceiveMemoryWarning. UIViewController如果当前视图未显示,它会在低内存系统中自动调用。你应该释放那里的东西IBOutlets,这将导致实际的视图被释放,这很好,因为如果它们最终再次显示viewDidLoad将首先被调用。

didReceiveMemoryWarning在某些情况下仍然适用,如果您有某种内存,即使UIViewController正在显示(如缓存)也可以摆脱。

于 2009-08-05T23:21:31.077 回答