当iPhone 3G和iPhone4没有时,iPad崩溃了

时间:2012-01-10 09:12:43

标签: iphone ios ipad cocos2d-iphone

我认为这是一个记忆问题,但我不确定该怎么做。

我的问题:

我几乎完成了一个使用cocos2d for iphone的游戏,使用了retina gfx,我已经使应用程序具有通用性,并且做了调整以使其在iPad上正常运行,大多数情况下我在ipad上使用视网膜spritesheets ,附加一些图像(包含在-hd spritesheets中)以覆盖屏幕边缘等。

一切正常,iPad在游戏中以60fps的速度运行,就像在iphone4上一样(我通常在iphone3g上大约需要40-50fps),但偶尔会在5分钟左右之间在菜单之间移动iPad(通常,但并不总是,在卸载游戏引擎并返回菜单后),游戏失败。

在调试器中,我收到“收到内存警告”,不久之后(不是立即)加载新的spritesheet或图形(不是创建sprite,而是实际将新纹理加载到内存中),应用程序关闭,我在控制台中获得的所有内容都是'(gdb)',没有堆栈跟踪。

我很难找到解决方案,当从我的游戏引擎移动到我的菜单时,我有一个加载屏幕,主要是使用1个全屏图像创建的,还有一些文本,所有其他纹理,spriteframes和预加载的soundfx然后在加载任何新内容之前从内存中清除。

我试图在仪器中运行带有泄漏和分配的ipad,但是一旦应用程序加载,仪器每次都会崩溃。

有没有人碰巧知道ipad应用程序在关闭之前的最大内存空间是什么(我以为我至少得到3个警告,而不是1),还有多少2048 x 2048张相同呢?

编辑:(发现了无理性记忆消失的新原因!)

所以,几周后,我在cocos2d论坛上偶然发现了这篇文章。

http://www.cocos2d-iphone.org/forum/topic/31092

iOS5中的这个错误很可能是我遇到麻烦的主要原因,在我看来,所有建议和建议都有助于整个我的应用程序收紧。

4 个答案:

答案 0 :(得分:2)

消耗更少的内存。使用CCTextureCache。请记住,Cocos2D始终保存宽度/高度为2的幂的图像。因此,如果您的图像是513像素,它将使用1024像素的图像。

CCTexture2D *texture = [[CCTextureCache sharedTextureCache] addImage:@"randomImage.png"];
CCSprite *randomImage = [CCSprite spriteWithTexture:texture];

为了节省更多内存,您可以使用纹理图集来查看。无论何时切换到菜单或游戏,您都可以调用removeUnusedTextures(或者当调用outofmemory时)。

[[CCTextureCache sharedTextureCache] removeUnusedTextures];

您还可以使用质量较低的图像来节省内存。

[CCTexture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGBA4444];

每当您需要加载更高质量的图像或渐变时,您都可以将它放回去。

[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];

答案 1 :(得分:1)

猜测,听起来好像内存警告导致了某个地方的双重释放。

这里要做的第一件事是启用Zombie对象。以前,您在Target的参数中设置了NSZombieEnabled。最近,Xcode为Zombies添加了UI支持。这可以在以下网址找到:

管理方案...>编辑...>诊断>启用Zombie Objects

这将导致调试器在检测到正在访问已发布的对象时断点,并且应该为您提供堆栈跟踪以帮助诊断。

在模拟器中进行测试时,可以手动生成内存警告。这可以在以下网址找到:

iOS模拟器>硬件>模拟记忆警告

另一种方法是向UI添加操作以简单地分配更多内存,这可以在触发崩溃之前使用。只需拨打malloc即可:

- (IBAction)simulateMemoryLeak
{
    malloc(1024 * 1024 * 10); // Leak 10MB of memory.
}

仪器崩溃很难诊断,但我发现Xcode的干净重新安装已经修复了仪器崩溃问题。

请注意,Instruments使用 Release 配置运行,而正常调试使用 Debug 配置,因此请检查您是否可以在发布下运行在尝试使用Instruments运行之前正常配置。

在iPad上使用视网膜图形会占用大量内存,因此请确保正确卸载UIImageView个插座。

特别是,请确保您了解View Controller Lifecycle并在viewDidUnload(在内存条件较低时调用)而不仅仅是dealloc中卸载视图出口。

View Controller Lifecycle

为了帮助进一步诊断,请尝试包含您可以提供的有关如何构建菜单UI的更多信息(您说明这可能是导致崩溃的原因)以及您如何进行内存管理(使用ARC,使用自动释放池等。)

答案 2 :(得分:0)

你有一个viewDidUnload方法,它释放你还需要的东西吗?当你收到内存警告时会调用它,所以你必须小心自由。只需使用它来释放可以在需要时重新加载的东西。

答案 3 :(得分:0)

谷歌向我指出了这篇文章的方向。

http://www.raywenderlich.com/2361/how-to-create-and-optimize-sprite-sheets-in-cocos2d-with-texture-packer-and-pixel-formats

将各种spritesheets设置为像素格式RGBA4444似乎已经停止了崩溃。我只能假设我用我加载到内存中的精灵来达到iPad的物理内存限制。