Cocos2d,iOS:从缓存中删除精灵的正确方法是什么?

时间:2012-09-17 08:51:41

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

我有一个单个实例的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 - 每个背景都有一个精灵表。)

有什么建议吗?

2 个答案:

答案 0 :(得分:4)

你可以用这个..

 [[CCSpriteFrameCache sharedSpriteFrameCache] removeSpriteFrames];

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

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

答案 1 :(得分:1)

编辑:

我假设您正在某处添加CCSpriteBatchNode节点,虽然您发布的代码没有显示它(您还提到,它发生在交换机中,因此我认为在完全不同的设置中)。如果是这样,除非将其从添加到的位置删除,否则不会取消分配。

在这里,也许,澄清是有序的。

CCSpriteFrameCache是一个缓存:一个存储区,所有精灵都可以使用,以便随时可以重复使用。

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

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

关于你的问题:

  

换句话说,在清理时调用“removeUnusedSpriteFrames”是否足够?

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

希望这会有所帮助。

  

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

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

 CCSpriteFrameCache* frameCache = [CCSpriteFrameCache sharedSpriteFrameCache];

所以,我不担心Cache没有被删除;重要的是它的内容是空的。