你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> 分析iOS開辟中Cocos2d-x的內存治理相干操作

分析iOS開辟中Cocos2d-x的內存治理相干操作

編輯:IOS開發綜合

一,IOS與圖片內存
在IOS上,圖片會被主動縮放到2的N次方年夜小。好比一張1024*1025的圖片,占用的內存與一張1024*2048的圖片是分歧的。圖片占用內存年夜小的盤算的公式是;長*寬*4。如許一張512*512 占用的內存就是 512*512*4 = 1M。其他尺寸以此類推。(ps:IOS上支撐的最年夜尺寸為2048*2048)。

二,cocos2d-x 的圖片緩存
Cocos2d-x 在結構一個精靈的時刻會應用spriteWithFile或許spriteWithSpriteFrameName等 不管用哪一種方法,cocos2d-x都邑將這張圖片加載到緩存中。假如是第一次加載這個圖片,那就會先將這張圖片加載到緩存,然後從緩存讀取。假如緩存中曾經存在,則直接從緩存中提取,免去了加載進程。

圖片的緩存重要由以下兩個類來處置:CCSpriteFrameCache, CCTextureCache

CCSpriteFrameCache加載的是一張拼接過的年夜圖,每個小圖只是年夜圖中的一個區域,這些區域信息都在plist文件中保留。用的時刻只須要依據小圖的稱號便可以加載到這個區域。

CCTextureCache 是通俗的圖片緩存,我們一切直接加載的圖片都邑默許放到這個緩存中,以進步挪用效力。

是以,每次加載一張圖片,或許經由過程plist加載一張拼接圖時,都邑將整張圖片加載到內存中。假如不去釋放,那就會一向占用著。

三,襯著內存
不要認為,盤算內存時,只盤算加載到緩存中的內存便可以了。以一張1024*1024的圖片為例。

CCSprite *pSprite = CCSprite::spriteWithFile("a.png");

挪用上邊這行代碼今後,可以在LEAKS對象中看到,增長了年夜約4M的內存。然後接著挪用

addChild(pSprite);

這時候,內存又增長了4M。也就是,一張圖片,假如須要襯著的話,那它所占用的內存將要X2。

再看看經由過程plist加載的圖片,好比這張年夜圖尺寸為2048*2048。想要加載個中的一張32*32的小圖片

CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("b.plist");

此時內存增長16M (汗)

CCSprite *pSpriteFrame = CCSprite::spriteWithSpriteFrameName("b1.png");

b.png 年夜小為32*32 ,想著也就是增長一點點內存,可現實情形是增長16M內存。也就是只需襯著了個中的一部門,那末整張圖片都要一路被加載。

然則情形不是那末的蹩腳,這些曾經襯著的圖片,假如再次加載的話,內存是不會再持續降低的,好比又增長了100個b.plist的另外一個區域,圖片內存照樣共增長16+16 = 32M,而不會持續上升。

四,緩存釋放
假如游戲有許多場景,在切換場景的時刻可以把前一個場景的內存全體釋放,避免總內存太高.

CCTextureCache::sharedTextureCache()->removeAllTextures(); 釋放到今朝為止一切加載的圖片

CCTextureCache::sharedTextureCache()->removeUnusedTextures(); 將援用計數為1的圖片釋放失落CCTextureCache::sharedTextureCache()->removeTexture(); 零丁釋放某個圖片

CCSpriteFrameCache 與 CCTextureCache 釋放的辦法差不多。

值得留意的是釋放的機會,普通在切換場景的時刻釋放資本,假如從A場景切換到B場景,挪用的函數次序為B::init()---->A::exit()---->B::onEnter() 可假如應用了切換後果,好比CTransitionJumpZoom::transitionWithDuration如許的函數,則函數的挪用次序變成B::init()---->B::onEnter()---->A::exit() 並且第二種方法會有一剎時將兩個場景的資本疊加在一路,假如不采用過度,極可能會由於內存吃緊而瓦解。

有時強迫釋放全體資本時,會使某個正在履行的動畫掉去援用而彈出異常,可以挪用CCActionManager::sharedManager()->removeAllActions();來處理。

5、內存治理
1.概述
cocos2d-x最後移植自cocos2d的objective C版本。是以,在內存治理上,應用了和NSObject相似的援用計數器辦法,相干接口放置在CCObject類中。

2.援用計數器——手動治理內存
CCObject的及其子類的對象在創立時,援用計數主動設置為1。以後每次挪用retain,援用計數+1。每次挪用release,援用計數-1;若援用計數=0,則直接delete this。
相干接口以下:
 
//援用次數+1
virtual void CCObject::retain(void);
//援用次數-1;若援用計數器=0,則delete this;
virtual void CCObject::release(void);
//helper辦法,疾速斷定以後對象只要獨一援用
bool CCObject::isSingleRefrence(void);
//前往援用次數
unsigned int CCObject::retainCount(void);

准繩1:誰生成(new、copy)誰擔任release。
例子:
CCObject *obj=new CCObject;
...
obj->release();

retain是在指針傳遞和賦值時應用的,他的寄義是表現具有。這常常用在指針賦值上。
准繩2:誰retain,誰擔任release。
例子:


obj->retain();
...
obj->release();

准繩3:傳遞賦值時,須要先retain形參,後release原指針,最初賦值。(留意,由於這裡沒有應用自賦值檢討,所以這組次序不克不及錯。)
例子:

void CCNode::setGrid(CCGridBase* pGrid)
{
            CC_SAFE_RETAIN(pGrid);
            CC_SAFE_RELEASE(m_pGrid);
            m_pGrid = pGrid;
}

 
3.主動釋放池——主動治理內存
 
准繩4:關於應用autorelease的對象,不用管它,每幀停止後會主動釋放。

相干接口:

CCObject* CCObject::autorelease(void);
 
例子:

CCObject *obj=new CCOjbect;
obj->autorelease();
...

完整手動治理內存,很繁瑣,cocos2d-x供給了主動釋放池CCPoolManager。將對象置於主動釋放池中,每幀繪制停止,就主動release池中的對象。

 
4.CCNode節點治理

cocos2d-x應用節點構成一棵樹,襯著的時刻要遍歷這棵樹。CCNode是一切節點類的父類,他外部應用了一個CCArray對象治理他的一切子節點,當對象被添加為子節點時,現實上是被添加到CCArray對象中,同時會挪用這個對象的retain辦法。同理,從CCArray中移除時,也會挪用release辦法。
 
相干接口:

virtual void addChild(CCNode * child);
virtual void addChild(CCNode * child, int zOrder);
virtual void addChild(CCNode * child, int zOrder, int tag);
virtual void removeChild(CCNode* child, bool cleanup);
void removeChildByTag(int tag, bool cleanup);
virtual void removeAllChildrenWithCleanup(bool cleanup);

在切換場景時,體系會遍歷整棵樹的節點,停止release。

5.靜態工場

cocos2d-x中存在年夜量的靜態工場辦法,這些辦法中,全都對this指針挪用了autorelease函數。如CCSprite中的這些辦法:

static CCSprite* spriteWithTexture(CCTexture2D *pTexture);
static CCSprite* spriteWithTexture(CCTexture2D *pTexture, const CCRect& rect);
static CCSprite* spriteWithTexture(CCTexture2D *pTexture, const CCRect& rect, const CCPoint& offset);
static CCSprite* spriteWithSpriteFrame(CCSpriteFrame *pSpriteFrame);
static CCSprite* spriteWithSpriteFrameName(const char *pszSpriteFrameName);
static CCSprite* spriteWithFile(const char *pszFileName);
static CCSprite* spriteWithFile(const char *pszFileName, const CCRect& rect);
static CCSprite* spriteWithDosBat target=_blank class=infotextkey>BatchNode(CCSpriteDosBat target=_blank class=infotextkey>BatchNode *DosBat target=_blank class=infotextkey>BatchNode, const CCRect& rect);
 
這些辦法外部完成了:內存分派、初始化、設置autorelease。用靜態工場來生成對象,可以簡化代碼,是官方建議的辦法。

6.cache機制類

cocos2d-x中存在一些cache類,這些都是單例類的治理器。

CCAnimationCache
CCSpriteFrameCache
CCTextureCache

這些cache外部也應用了ratain和release辦法,避免這些資本被釋放失落。
應用這些cache,我們可以保留預加載的一些資本,在便利的時刻挪用它,去綁定給一些對象。留意,這些cache在場景切換時,不會主動刪除,須要手動挪用purgeXXXX辦法,停止清算。

【分析iOS開辟中Cocos2d-x的內存治理相干操作】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved