cocos2d-x CCSpriteFrameCache类使用总结

来源:互联网 发布:paperpass 淘宝 编辑:程序博客网 时间:2024/05/18 09:03

写这篇的出发点是因为我需要手动修改素材的像素,目前的接口要修改很容易,但是会造成内存管理,key冲突等问题,为了形成一个较优的方案,先研究下引擎自身的实现。

主要从缓存中的对象的产生->使用->回收角度来看,如果我描述的有什么问题,欢迎交流。


一、加载plist文件到内存

一般从plist加载到CCSpriteFrameCache使用该方法:void CCSpriteFrameCache::addSpriteFramesWithFile(const char *pszPlist)

step 1.首先调用CCTexture2D * CCTextureCache::addImage(const char * path)产生CCTexture2D 对象,

step 2.调用void CCSpriteFrameCache::addSpriteFramesWithDictionary(CCDictionary* dictionary, CCTexture2D *pobTexture)方法

在这个方法中,将会产生CCSpriteFrame对象并管理起来,同时将step 1产生CCTexture2D 对象关联给CCSpriteFrame对象并retain。

此时,CCSpriteFrame对象的计数是1, CCTexture2D 计数是1+被关联次数;


二、使用Cache中的CCSpriteFrame对象

step1.我们使用CCSpriteFrame* CCSpriteFrameCache::spriteFrameByName(const char *pszName)方法从cache中获得CCSpriteFrame对象

step2.将CCSpriteFrame关联给CCAnimationFrame并retain(CCAnimationFrame析构时会调用CCSpriteFrame的release)

step3.给CCprite播放动画,动画播放过程会调用CCSprite::setDisplayFrame(CCSpriteFrame *pNewFrame),该方法会对CCTexture2D 对象retain一次,析构会release


从上分析可知:

1、使用过程中CCSpriteFrameCache中的CCSpriteFrame对象计数可能会改变,但是使用完毕后该计数会恢复,正常使用不存在外部释放资源的可能。

2、CCTextureCache的CCTexture2D 对象同上

3、两个Cache类中的资源是恒存在的,需要释放必须手动释放,否则内存占用会越来越大。

大概代码样例如下:

string pics[] = {"66Made_JG_28_Trans_0_0.png","66Made_JG_28_Trans_0_1.png", "66Made_JG_28_Trans_1_0.png", "66Made_JG_28_Trans_1_1.png", "66Made_JG_28_Trans_2_0.png", "66Made_JG_28_Trans_2_1.png", "66Made_JG_28_Trans_3_0.png", "66Made_JG_28_Trans_3_1.png", "66Made_JG_28_Trans_4_0.png", "66Made_JG_28_Trans_4_1.png","66Made_JG_28_Trans_5_0.png", "66Made_JG_28_Trans_5_1.png","66Made_JG_28_Trans_6_0.png", "66Made_JG_28_Trans_6_1.png","66Made_JG_28_Trans_7_0.png", "66Made_JG_28_Trans_7_1.png","66Made_JG_28_Trans_8_0.png", "66Made_JG_28_Trans_8_1.png"};CCArray *animateFrames = CCArray::createWithCapacity(20);CC_RETURN_FALSE_IF(!animateFrames);CCSpriteFrame *pFrame = NULL;for (auto a : pics){string frameName = a + D_TextureManager->getSuffix(textureInfo);pFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(frameName.c_str());CC_RETURN_FALSE_IF(!pFrame);animateFrames->addObject(pFrame);}CCAnimation *pAnimation = CCAnimation::createWithSpriteFrames(animateFrames, 0.1f);animateFrames->release();                                CCSprite *pSprite1 = CCSprite::create();CC_RETURN_FALSE_IF(!pSprite1);this->addChild(pSprite1);pSprite1->setPosition(ccp(size.width/2, size.height/2));pSprite1->runAction(CCAnimate::create(pAnimation));

三、如何合理回收这部分资源

step1.回收CCSpriteFrameCache中的CCSpriteFrame对象:建议使用void CCSpriteFrameCache::removeSpriteFramesFromFile(const char* plist)方法回收

step2.回收CCTextureCache中的CCTexture2D 对象:建议使用void CCTextureCache::removeUnusedTextures()方法回收


注意:removeSpriteFramesFromFile会对关联的CCTexture2D 对象进行release操作,在CCSpriteFrame回收完的情况下,CCTexture2D 的计数为1。

原创粉丝点击