Cocos場景切換時清理緩存!!CCTextureCache、CCSpriteFrameCache、CCAnimationCache

cocos2d-x中存在3個緩存類,都是全局單例模式。

1.CCTextureCache

首先是最底層也最有效的紋理緩存CCTextureCache,這裏緩存的是加載到內存中的紋理資源,也就是圖片資源。其原理是對加入緩存的紋理資源進行一次引用,使其引用計數加一,保持不被清除,其cocos2d-x的渲染機制是可以重複使用同一份紋理在不同的場合進行繪製,從而到達重複使用,降低內存和CPU運算資源的開銷的目的。常用的是如下所示的3個接口:

static CCTextureCache* sharedTextureCache(); //返回紋理緩存的全局單例

CCTexture2D* addImage(const char* fileimage); //添加一張紋理圖片到緩存中

void removeUnusedTextures(); //清除不使用的紋理

在這3個接口中,CCTextureCache屏蔽了加載紋理的許多細節;addImage函數會返回一個紋理CCTexture2D的引用,可能是新加載到內存的,也可能是之前已經存在的;而removeUnusedTextures則會釋放當前所有引用計數爲1的紋理,即目前沒有被使用的紋理。

實際上,我們很少需要調用addImage這個接口,因爲引擎內部所有的紋理加載都是通過這個緩存進行的,換句話說,載入的每一張圖片都被緩存了,所以我們更需要關心什麼時候清理緩存。引擎會在設備出現內存警告時自動清理緩存,但是這顯然在很多情況下已經爲時已晚了。一般情況下,我們應該在切換場景時清理緩存中的無用紋理,因爲不同場景間使用的紋理不同的。如果確實存在着共享的紋理,將其加入一個標記數組來保持其引用計數,以避免被清理。

2.CCSPriteFrameCache

第二個則是精靈框幀緩存。顧名思義,這種緩存的精靈框幀CCSpriteFrame,它主要服務於多張碎圖合併出來的紋理圖片。這種紋理在一張大圖中包含了多張小圖,直接通過CCTextureCache引用會有諸多不便,因而衍生出來精靈框幀的處理方式,即把截取好的紋理信息保存在一個精靈框幀內,精靈通過切換不同的幀來顯示不同的圖案。

CCSpriteFrameCache的常用接口和CCTextureCache類似,不在贅述了,唯一需要注意的是添加精靈幀的配套文件——一個plist文件和一張大的紋理圖。下面列舉了CCSpriteFrameCache常用的方法:

static CCSPriteFrameCache* sharedSpriteFrameCache(); //全局共享的緩存單例

void addSpriteFrameWithFile(const char *pszPlist); //通過plist配置文件添加一組精靈幀

void removeUnusedSpriteFrames(); //清理無用緩存

3.CCAnimationCache

最後一個是CCAnimationCache動畫的緩存。通常情況下,對於一個精靈動畫,每次創建時都需要加載精靈幀,按順尋添加到數組,在創建對應動作類,這是一個非常煩瑣的計算過程。對於使用頻率高的動畫,比如魚的遊動,將其加入緩存可以有效降低每次創建的巨大消耗。由於這個類的目的和緩存內容都非常簡單直接,所以其接口也是最簡單了的,如下所示:

static CCAnimationCache* sharedAniationCache(); //全局共享的單例

void addAnimation(CCAnimation *animation, const char *name); //添加一個動畫到緩存

void removeAnimationByName(const char *name); //移除一個指定的動畫

CCAnimation* animationByName(const char *name); //獲得事先存入的動畫

唯一不一樣的是,這次動畫緩存需要我們手動維護全部動畫信息。也因爲加載幀動畫完全是代碼操作的,目前還沒有配置文件指導,所以不能像另外兩個緩存那樣透明化。實際上,如果考慮到兩個場景間使用的動畫基本不會重複,可以直接清理整個動畫緩存。

所以,在場景切換時我們應該加入如下的清理緩存操作:

void releaseCaches() {

CCAnimationCache::purgeSharedAnimationCache();

CCSpriteFrameCache::sharedSpriteFrameCache()->removeUnusedSpriteFrames();

CCTextureCache::sharedTextureCache()->removeUnuserdTextures();
}

值得注意的是清理的順序,應該先清理動畫緩存,然後清理精靈幀,最後是紋理。按照引用層級由高到低,以保證保釋引用有效。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章