iPhone内存管理确实收到了内存警告

时间:2009-05-28 15:09:41

标签: iphone memory-management

确定......

我正在iPhone上实现一个简单的OpenGL ES应用程序,最近我在Pinch Media Analytics中添加了该应用程序。这样做有助于发现内存管理问题,我并不完全确定如何处理它。

在一个完美的世界中,我的应用程序 - 在didFinishLoading中加载PNG和.CAF文件将启动,加载所有资源,并运行得很好。

然而,如果我的程序崩溃(发生在我整合Pinch Media库时),或者如果我运行Safari并打开一堆页面然后启动我的游戏,游戏将崩溃回菜单,因为它是记忆力不足。

此问题将持续存在,直到我对系统进行硬重置。

您上网的默认答案是实现下面列出的didReceiveMemoryWarning方法....

- (void)didReceiveMemoryWarning
{ 
  // default behavior is to release the view if it doesn't have a superview.

  // remember to clean up anything outside of this view's scope, such as
  // data cached in the class instance and other global data.
  [super didReceiveMemoryWarning];
}

但这并没有真正帮助,因为它是其他程序,而不是我的内存。我不想发布自己的观点吗?是否有很好的描述如何处理这种情况和/或didReceiveMemoryWarning事件中发生的事情?

3 个答案:

答案 0 :(得分:5)

欢迎使用没有VM的共享内存池....你可以在这里做很多事情,但有一些事情(这可能是你的错,你可以完全解决它)。游戏开发者经常建议他们的客户在运行之前重新启动,因此如果你真的需要大量的内存才能有效,你可能需要在同一条船上。

当然,您应该尽量减少自己的内存占用。但是你也应该尽量避免过多的内存碎片。有时问题不在于没有记忆;没有足够大的块。有时最好使用Mutable并继续修改它而不是生成一个新的不可变对象。对于大型NSStrings来说尤其如此,这可能真的会破坏内存。

请注意,UIImage +imageNamed:会在您释放后保留图像,所以如果您不再需要它们,则需要清除它们。在释放之前将其名称设置为nil以停止缓存。

确保在“工具”下运行您的应用。你可能吃的东西比你想象的要多。

不要忘记自动释放池。如果在单个事件循环中生成大量自动释放的对象,则可能需要定期耗尽池,以免引发内存。内存峰值可能会导致程序具有适度的内存需求而突然被杀死。

答案 1 :(得分:2)

如果您只有一个视图,那么您唯一可以做的就是释放您未使用的任何数据,并在以后延迟加载它们。

如果您有多个视图,那么如果它们不可见,它们可能会被释放。如果发生这种情况,相应的控制器将setView:nil一起发送。我通过立即释放所有IBOutlet变量来处理这种情况,以便在从xib再次加载视图时正确设置它们。

这是我在普通的非OpenGL ES应用程序中采用的方法,该应用程序具有> 6个​​视图,并且即使我在导航视图中处于4级深度并且所有先前的控制器将其视图设置为{{ 1}} - 当我向后导航时没有崩溃,尽管在重新加载视图时会有延迟。

如果您还没有找到它,在模拟器中有一个菜单项来模拟内存警告,这比强制在真实设备中发生条件更容易。也就是说,它不会取代在真实设备中测试相同的场景 - 只是简化测试。

答案 2 :(得分:0)

您可以尝试使用压缩PVRTC而不是使用PNG,以节省一些空间(可能会降低性能)。

这里有一个很好的小教程:

http://iphonedevelopment.blogspot.com/2008/12/preparations-for-porting-nehe-lesson-06.html

请记住,您必须重写一些OpenGL调用来处理这种不同的压缩纹理。

[免责声明:我不是OpenGL ES优化专家。不是通过一个looooong射击。]