【问题标题】:iPad Crashes when iPhone 3G and iPhone4 does not当 iPhone 3G 和 iPhone4 不运行时 iPad 崩溃
【发布时间】:2012-02-06 17:15:34
【问题描述】:

我认为这是一个内存问题,但我不确定在这里做什么。

我的问题:

我几乎完成了一个使用 cocos2d for iphone 和retina gfx 的游戏,我已经使该应用程序通用,并进行了调整以使其在 iPad 上正常运行,我主要使用 iPad 上的视网膜 spritesheets ,以及一些额外的图像(包含在 -hd spritesheets 中)以覆盖屏幕边缘等。

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

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

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

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

有没有人碰巧知道 ipad 应用程序在关闭之前的最大内存空间是多少(我想我至少会收到 3 个警告,而不是 1 个),这也等于多少 2048 x 2048 张?

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

几周后,我偶然发现了 cocos2d 论坛上的这篇帖子。

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

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

【问题讨论】:

  • 您是否为可执行文件启用了 NSZombieEnabled ? cocoadev.com/index.pl?NSZombieEnabled
  • 崩溃日志没有告诉你什么吗?
  • 没有可以依赖的固定内存量,如果您使用的内存超出操作系统可以为您释放的内存量,操作系统会杀死您的应用程序。如果我没记错的话,ipad 的内存只有 iphone4 的一半,而且您使用的是相同的大图像。可能是您泄漏了一些东西。您可以加载许多 2048x2048 纸张而不会出现重大问题
  • 我目前关闭了 NSZombieEnabled,游戏不会因为向已释放实例发送消息而崩溃,(我在 ipad、iphone3g 和 iphone4 上检查过)它只会在收到内存警告
  • 崩溃日志中没有任何内容,保罗

标签: iphone ios ipad cocos2d-iphone


【解决方案1】:

猜测一下,听起来好像内存警告正在某处导致双重释放。

首先要做的是启用 Zombie 对象。以前,您会在 Target 的参数中设置 NSZombieEnabled。最近,Xcode 增加了对 Zombies 的 UI 支持。这可以在以下位置找到:

管理方案...> 编辑...> 诊断 > 启用僵尸对象

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

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

iOS 模拟器 > 硬件 > 模拟内存警告

另一种方法是向您的 UI 添加一个操作来简单地分配更多内存,这些内存可以一直使用到触发崩溃为止。对malloc 的简单调用就足够了:

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

Instruments 崩溃很难诊断,但我发现重新安装 Xcode 已经为我解决了过去的 Instruments 崩溃问题。

注意 Instruments 使用 Release 配置运行,而正常调试使用 Debug 配置,所以请检查您是否可以在 Release 下运行strong> 在尝试使用 Instruments 运行之前通常进行配置。

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

特别是,确保您了解 View Controller Lifecycle 并正在卸载 viewDidUnload(在内存不足的情况下调用)中的视图出口,而不仅仅是 dealloc

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

【讨论】:

    【解决方案2】:

    你有没有一个 viewDidUnload 方法来释放你仍然需要的东西?这将在您收到内存警告时调用,因此您必须小心释放的内容。只需使用它来释放可以在需要时重新加载的内容。

    【讨论】:

      【解决方案3】:

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

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

      为了节省更多内存,您可以考虑使用纹理图集。每当您切换到菜单或游戏时,您都可以调用 removeUnusedTextures(或者当内存不足时)。

      [[CCTextureCache sharedTextureCache] removeUnusedTextures];
      

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

      [CCTexture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGBA4444];
      

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

      [CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
      

      【讨论】:

      • 我在发布答案之前没有刷新页面,但是我会给你赏金,因为这个答案无疑会引导我找到解决方案。
      • 我不能再奖励它 21 小时,我明天再奖励。
      • cocos2d-iphone.org/forum/topic/31092 - 这也可能是导致问题的主要原因。
      【解决方案4】:

      Google 为我指明了本文的方向。

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

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

      【讨论】:

        猜你喜欢
        • 2015-04-26
        • 2012-05-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多