我认为这是一个记忆问题,但我不确定该怎么做。
我的问题:
我几乎完成了一个使用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中的这个错误很可能是我遇到麻烦的主要原因,在我看来,所有建议和建议都有助于整个我的应用程序收紧。
答案 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
中卸载视图出口。
为了帮助进一步诊断,请尝试包含您可以提供的有关如何构建菜单UI的更多信息(您说明这可能是导致崩溃的原因)以及您如何进行内存管理(使用ARC,使用自动释放池等。)
答案 2 :(得分:0)
你有一个viewDidUnload方法,它释放你还需要的东西吗?当你收到内存警告时会调用它,所以你必须小心自由。只需使用它来释放可以在需要时重新加载的东西。
答案 3 :(得分:0)
将各种spritesheets设置为像素格式RGBA4444似乎已经停止了崩溃。我只能假设我用我加载到内存中的精灵来达到iPad的物理内存限制。