天天看點

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();

}

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

繼續閱讀