【问题标题】:Cocos2d, iOS: what is the correct way to remove sprites from cache?Cocos2d,iOS:从缓存中删除精灵的正确方法是什么?
【发布时间】:2012-09-17 08:51:41
【问题描述】:

我得到了一个不是单例实例的 GameScene 类。因此,每次用户选择新关卡时,我都会分配和取消分配它,并将“静态”/“共享”数据保存在不同的单例类(例如 GameManager)中。

我正在使用 ARC。我想了解在内存管理的角度下我的方法是否正确。换句话说,在清理时调用“removeUnusedSpriteFrames”就足够了吗?这会删除 game-art-forLevelOne-hd.plist 中的所有精灵吗?我也应该对 CCSpriteBatchNode 做点什么吗?

-(void) loadGameArtFileForLevelOne  //I do this in a switch but this is to simplify the reading 
{
    CCSpriteFrameCache* frameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
    [frameCache addSpriteFramesWithFile:@"game-art-forLevelOne-hd.plist"];
    CCSpriteBatchNode * sharedSpriteBatchNode = [CCSpriteBatchNode batchNodeWithFile:@"game-art-forLevelOne-hd.png"];    
 }

//As dealloc is deprecated for ARC code, I prefer to remove unused sprites and texture on cleanup
-(void) cleanup
{
    [[CCSpriteFrameCache sharedSpriteFrameCache] removeUnusedSpriteFrames];     
}

我在 CCSpriteBatch 节点的 dealloc 方法中添加了一个 CCLOG 调用。当我加载 GameScene 然后返回菜单时,我看到了“删除未使用的纹理”的日志,但 我没有看到 CCSpriteFrameCache 的 dealloc 方法的任何日志。 * !!警告:请参阅下面的编辑 - 我的错误!*

编辑:抱歉,我的意思是我没有看到 CCSpriteBatch 的 dealloc 方法的任何日志

这让我有点担心,因为我想“释放”并删除与关卡 Sprite 相关的所有内存。

一旦我理解了这一点,我就会“优化”这一点(例如,每个级别都有一个精灵表 - 例如世界 1 - 并且每个背景都有一个精灵表)。

有什么建议吗?

【问题讨论】:

  • dealloc 方法没有被弃用,你仍然可以使用它。不再允许在 dealloc 中调用 [super dealloc]。

标签: iphone caching cocos2d-iphone automatic-ref-counting sprite


【解决方案1】:

你可以用这个..

 [[CCSpriteFrameCache sharedSpriteFrameCache] removeSpriteFrames];

如果您需要更多,请使用关注。

[[CCDirector sharedDirector] purgeCachedData];
[[CCTextureCache sharedTextureCache] removeAllTextures];
[CCTextureCache purgeSharedTextureCache];
[[CCSpriteFrameCache sharedSpriteFrameCache] removeSpriteFrames];
[CCSpriteFrameCache purgeSharedSpriteFrameCache];

【讨论】:

  • 您能解释一下这些方法的作用吗?我查看了 Doxygen 文档并不清楚。
【解决方案2】:

编辑:

我假设您在某处添加了 CCSpriteBatchNode 节点,尽管您发布的代码没有显示它(您还提到,它发生在开关中,所以我认为在完全不同的设置中)。如果是这样,它不会被释放,直到您从添加它的位置删除它。

在这里,也许需要澄清一下。

CCSpriteFrameCache 是一个缓存:一个存储区,所有精灵都可以在其中获取以便随时可以重用。

CCSpriteBatchNode 是一种提高 Open GL 层性能的机制,原则上与缓存完全无关。

我了解,如果您通过批处理节点使用的某些精灵仍然存在于某些层/节点/场景中,则它不会被视为“未使用”并且不会被您的清理代码删除。实际上,它正在使用中。当您从所有引用它的节点中删除它时,缓存的 sprite 将变为“未使用”。

关于你的问题:

也就是说,清理时调用“removeUnusedSpriteFrames”就够了吗?

嗯,我认为这取决于您的应用程序什么可以被认为是好的清理。从缓存中删除未使用的精灵当然可以;但你也可以做其他事情:卸载你加载的音频资源;删除场景中未使用的部分(如果需要,可以重新加载);等等

希望这会有所帮助。

我没有看到 CCSpriteFrameCache 的 dealloc 方法的任何日志。

CCSpriteFrameCache 是一个单例,所以它应该在程序的整个生命周期内都存在(它可能会有所不同,但我敢打赌就是这种情况):

 CCSpriteFrameCache* frameCache = [CCSpriteFrameCache sharedSpriteFrameCache];

所以,我不会担心缓存没有被删除;重要的是它的内容被清空了。

【讨论】:

  • 对不起,我的意思是 CCSpriteBatch。我看到 CCSpriteFrameCache 的日志调用(例如 cocos2d:CCSpriteFrameCache:删除未使用的帧:file0.png),但没有看到 CCSpriteBatch 的 dealloc 方法(我在那里添加了一个 CCLOG)。对此感到抱歉.. 我为我的努力投票并为我的拼写错误道歉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多