Memory 具有多个场景的Cocos2D项目无法正确释放内存

Memory 具有多个场景的Cocos2D项目无法正确释放内存,memory,cocos2d-iphone,automatic-ref-counting,kobold2d,Memory,Cocos2d Iphone,Automatic Ref Counting,Kobold2d,我有一个大问题,我不太明白为什么会发生。情况就是这样: 在Cocos2D中有一个很棒的项目,有10个场景。每个场景都是一本书的一页,里面有巨大的精灵。它使用Kobold2D 1.0.2实现 每个页面在单例类中都有公共对象,通过LayerColor放置公共菜单 精灵是PVR.CCZ RGBA4444和iPad内存中的TexturePacker 每个spritesheet加载大约16-20Mb 我使用CCTransitionTurnPage将一个场景替换为下一个场景 在每个页面(类)的init方法

我有一个大问题,我不太明白为什么会发生。情况就是这样:

  • 在Cocos2D中有一个很棒的项目,有10个场景。每个场景都是一本书的一页,里面有巨大的精灵。它使用Kobold2D 1.0.2实现
  • 每个页面在单例类中都有公共对象,通过LayerColor放置公共菜单
  • 精灵是PVR.CCZ RGBA4444和iPad内存中的TexturePacker 每个spritesheet加载大约16-20Mb
  • 我使用CCTransitionTurnPage将一个场景替换为下一个场景
  • 在每个页面(类)的init方法中,加载纹理和框架文件
  • 在每个页面(类)的onExit方法中,卸载纹理和框架文件。我使用了dumpCachedTextureInfo,并说我可以完美地从内存中加载和卸载纹理
  • 当然,我会从子对象中删除所有对象。我的所有精灵都是在.h的接口部分声明的公共变量,因为我需要在类的每个方法中访问它们
  • 我的项目是在ARC项目中使用Kobold2D集成制作的(但您知道,附加的Kobold2D项目没有启用ARC以解决兼容性问题)
事实上,当我开始这个项目时,一切似乎都很完美,但我制作的每个场景(页面)的内存都在增加。第1页:30Mb,第2页:40,第3页:54,第4页:65。。。在7或8个场景之后,Instruments、Xcode或iPad本身会挂起应用程序而不显示任何消息(带有最终内存不足警告的仪器除外)


为什么每一幕后都没有记忆释放?可能是因为ARC和no super dealoc变量。为什么纹理看起来卸载完美,但似乎没有卸载,因为内存在崩溃前不受控制地增长

我在内存保留方面也遇到了类似的问题,而且仪器中没有出现泄漏。在我将以下内容写入每个场景的.m文件之前,我甚至无法调用-(void)dealloc:

-(void) onExit {
    //unschedule selectors to get dealloc to fire off
    [self unscheduleAllSelectors];
    //remove all textures to free up additional memory. Textures get retained even if the sprite gets released and it doesn't show as a leak. This was my big memory saver
    [[CCTextureCache sharedTextureCache] removeAllTextures];
    [super onExit];
}

在实现这一点之后,每次调用replaceSecene:之后,我的内存都被释放。希望这对您有所帮助。

经过几个月的工作,我学到了关于Cocos2D的最重要的一课。将任何CCNode对象放在CCArray或NSArray或NSDictionary上时,保留增加1。。。这意味着您必须在CCLayer或CCScene解除锁定之前释放此对象中的对象

必须将[array removeAllObjects]或[dictionary release]放置在-(void)清理上,并在移除所有对象后,放置[super cleanup]

同时,在-(void)onExit上,必须从实例中删除所有调度程序。不仅仅是调度器本身。记住停止任何CCNode上的所有操作。但是,要小心,因为在删除任何RemoveAllObject之前,必须在清理时停止来自CCNodes(精灵或其他东西)的操作


请记住:如果CCLayer或CCScene未正确删除,SimpleAudioEngine也不会释放音频。

在场景的dealloc方法中设置断点,如果未调用dealloc,则有一个保留周期(ARC无法阻止,另请参见:)。特别要检查CCNode*属性是否有强属性或弱属性,它们应该设置为assign。最后,我必须设置为disabled ARC,因为场景中存在此保留循环。我找不到任何解决方案来对每个场景进行真正的解除锁定,我必须禁用ARC。当我这么做的时候,一切都很顺利。RemoveAllTextures现在冻结内存(ARC不冻结),超级dealloc可以完美工作。当我启用ARC时,override dealloc not fire,我使用onExit卸载纹理并冻结内存,但不起作用。非常感谢你的帮助!禁用圆弧很可能只会改变代码错误的行为方式,特别是如果您有一个圆形参考圆弧或没有圆弧,则不会有任何区别。很可能你现在正在悄悄地泄露物品。老实说。。。就像德雷德法官说的:“我就知道你会这么说!”。。。我想你是对的。我认为这只是一个补丁,因为应用程序在最后一个场景中增长到80Mb。如何检测此循环或泄漏。。。因为仪器没有显示任何关于纹理的信息,在某些情况下,纹理的重新计数超过20。非常感谢你的帮助!我总是使用[[CCTextureCache sharedTextureCache]removeUnusedTextures];认为Cocos2D会发现纹理确实未使用,从而将其删除。事实证明,它无法可靠地确定它,因此removeAllTextures(尽管速度较慢)更好地防止内存问题。此公式适用于圆弧或非圆弧项目。:)