ARC与cocos2d导致无限堆增长和最终内存崩溃?

时间:2015-09-18 03:27:19

标签: ios objective-c iphone cocos2d-iphone

我试图在游戏中追踪与记忆相关的崩溃。确切的错误,如果我碰巧在附加到调试器时捕获它会有所不同。一个这样的错误消息是:

  • Message from debugger: Terminated due to memory issue

不会生成崩溃报告。这是我在Memory Report上播放时来自XCode7 iPhone6的屏幕截图;大约10分钟后它会崩溃,因为我进入~600MB +范围:

enter image description here

使用乐器进行世代分析我发现通过战斗进行游戏似乎创造了无限的持续记忆增长;在这里你可以看到当我进行两场战斗时会发生什么: enter image description here

令人困惑的是,旋转显示的分配几乎是整个游戏中分配的内存的每一位。任何字典中的字符串读取,数组的任何分配,都会在此向下旋转中出现。这是钻取到NSArray来电分析的代表性示例:

enter image description here

此时,我发现几年前我使用cocos2d-iphone v2.1启动了这个项目,尽管使用了预ARC库,我还是开始了ARC项目。我想知道我现在是否意识到我配置了一些可怕的,可怕的错误。我在-fno-objc-arc文件上设置了cocos2d标记:

enter image description here

要不然,或者我必须做其他非常愚蠢的事情。但我不知所措。我检查了一些常见的罪魁祸首,例如:

  • 在我的NSLog子类中deallocCCScene以确保场景消失
  • 确保实施cleanup(清空缓存CCNode)并在我的子句中调用super
  • 转储cocos2d纹理缓存大小,并检查它没有增长无限制
  • 添加了低内存警告处理程序,例如清除cocos2d缓存

我也一直在倾倒the Apple instruments documentation,特别是这个链接解释了我为创建上一代分析所采取的步骤。

更新

这是另一个代表性示例,这次是树格式。你可以看到我有一个CCScheduler调用了一个更新函数,它触发了UI来绘制一个精灵。在您深入研究cocos2d代码之前,您最后一次看到我的代码是突出显示的函数,我也在下面粘贴了该代码。

enter image description here

+ (instancetype)spriteAssetSource:(NSString*)assetName {
  if(!assetName.length) {
    return nil;
  }
  BOOL hasImageSuffix = [assetName hasSuffix:EXT_IMG];
  NSString *frameName = hasImageSuffix ? [assetName substringToIndex:assetName.length-EXT_IMG.length] : assetName;
  NSString *hdFrameName = [NSString stringWithFormat:@"%@%@",frameName,EXT_HD];

  // First, hit up the sprite sheets...
  if([[CCSpriteFrameCache sharedSpriteFrameCache] hasSpriteFrameName:hdFrameName]) {
    CCSpriteFrame *frame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:hdFrameName];
    return [[self alloc] initWithSpriteFrame:frame];
  }
  // No sprite sheet? Try the assets.
  else {
    NSString *assetFp = hasImageSuffix ? assetName : [NSString stringWithFormat:@"%@%@",assetName,EXT_IMG];
    return [[self alloc] initWithFile:assetFp];
  }
}

关于这一点很奇怪的是,捕获的内存只是检查文件名是否在cocos2d缓存中的简单行:

- (BOOL)hasSpriteFrameName:(NSString*)name {
  return [_spriteFrames.allKeys containsObject:name];
}

然而,这个简单的功能在这些痕迹中显示出来......

它感觉的含义是我创建并传递给cocos2d的任何本地范围的变量都会使其保留计数递增,因此永远不会释放(例如hdFrameNameCCScheduler的情况上面的其他变量。)

更新2

虽然AMLocalPlayerData位于废弃对象树的顶部并不奇怪,但令人惊讶的是,有些对象与cocos2d或UI完全无关。例如,在突出显示的行中,我所做的就是调用执行[NSDate date]的{​​{1}}上的函数。整条线是: NSTimeInterval now = [NSDate date].timeIntervalSince1970;

NSDate对象在某种程度上可以保留在这里似乎很荒谬,但这似乎是乐器所暗示的......

enter image description here

更新3

我尝试将我的cocos2d版本升级到2.2 last version to exist in the repository。这个问题仍然存在。

0 个答案:

没有答案