亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

剖析iOS開發中Cocos2d-x的內存管理相關操作

2020-07-26 03:33:09
字體:
來源:轉載
供稿:網友

一,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();來解決。

五、內存管理
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* spriteWithBatchNode(CCSpriteBatchNode *batchNode, const CCRect& rect);
 

這些方法內部實現了:內存分配、初始化、設置autorelease。用靜態工廠來生成對象,可以簡化代碼,是官方建議的方法。

6.cache機制類

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

復制代碼 代碼如下:

CCAnimationCache
CCSpriteFrameCache
CCTextureCache

這些cache內部也使用了ratain和release方法,防止這些資源被釋放掉。
使用這些cache,我們可以保存預加載的一些資源,在方便的時候調用它,去綁定給一些對象。注意,這些cache在場景切換時,不會自動刪除,需要手動調用purgeXXXX方法,進行清理。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品专区h在线观看| 日韩av免费在线| 91香蕉亚洲精品| 久久精品中文字幕一区| 国产精品一区二区在线| 欧美日韩午夜剧场| 亚洲日本aⅴ片在线观看香蕉| 精品国内自产拍在线观看| 少妇高潮久久久久久潘金莲| 国自在线精品视频| 国产精品久久久久久久av电影| 国产精品极品美女在线观看免费| 国产美女久久精品香蕉69| 国产91色在线免费| 久久久国产91| 国产第一区电影| 少妇av一区二区三区| 欧美成年人视频网站| 国产精品视频网站| 色妞色视频一区二区三区四区| 中文字幕免费精品一区高清| 国产欧美 在线欧美| 91久久精品国产91久久性色| 久久久久久久久久久网站| 欧美理论电影网| 九九视频直播综合网| 欧美一二三视频| 亚洲а∨天堂久久精品9966| 亚洲精品理论电影| 日韩在线播放视频| 日韩欧美亚洲范冰冰与中字| 国产精品第二页| 亚洲精品国产免费| 中文字幕亚洲综合| 黄色一区二区在线观看| 亚洲第一网站男人都懂| 91精品久久久久久综合乱菊| 中文字幕欧美精品日韩中文字幕| 亚洲精选在线观看| 欧美一级bbbbb性bbbb喷潮片| 九九热这里只有精品免费看| 国产精品免费视频xxxx| 国产精品久久久久久久久久免费| 亚洲色图第三页| 亚洲第一视频网| 亚洲欧美成人精品| 亚洲欧美在线免费| 国产综合视频在线观看| 51ⅴ精品国产91久久久久久| 日韩一区二区三区在线播放| 国产一区欧美二区三区| 国产精品pans私拍| 日本aⅴ大伊香蕉精品视频| 成人在线免费观看视视频| 欧美日韩国产区| 日本成人激情视频| 日韩一区二区三区xxxx| 日韩精品在线免费播放| 中文字幕亚洲一区在线观看| 国产香蕉一区二区三区在线视频| 国产91成人在在线播放| 影音先锋日韩有码| 欧美高清在线观看| 亚洲精品自产拍| 日韩欧美一区二区三区| 一本色道久久88综合亚洲精品ⅰ| 国内精品国产三级国产在线专| 这里只有精品在线观看| 国内久久久精品| 久久久久久国产精品三级玉女聊斋| 欧美在线播放视频| 中文字幕日韩精品在线观看| 亚洲free嫩bbb| 怡红院精品视频| 中文在线资源观看视频网站免费不卡| 国语自产精品视频在免费| 亚洲欧美另类中文字幕| 色综合视频一区中文字幕| 亚洲激情久久久| 日本一区二区三区在线播放| 成人黄色在线观看| 精品国产91久久久久久| 亚洲天堂男人的天堂| 精品香蕉一区二区三区| 国产精品成av人在线视午夜片| 午夜欧美不卡精品aaaaa| 亚洲激情免费观看| 久久99青青精品免费观看| 国产人妖伪娘一区91| 亚洲第一精品自拍| 91伊人影院在线播放| 欧美性做爰毛片| 91在线观看免费高清| www.国产一区| 98精品国产高清在线xxxx天堂| 国产亚洲欧美aaaa| 国产欧美在线观看| 欧美性资源免费| 8x拔播拔播x8国产精品| 国产成人精品综合久久久| 久久国产精品影片| 九九热这里只有精品6| 久久久精品免费| 伊人伊成久久人综合网站| 亚洲欧洲成视频免费观看| 黄色一区二区在线| 成人黄色影片在线| 91高清视频免费| 国产精品wwww| 亚洲精品电影网在线观看| 国产啪精品视频网站| 精品国产精品三级精品av网址| 国产精品免费观看在线| 中国人与牲禽动交精品| 91社区国产高清| 丝袜亚洲另类欧美重口| 狠狠做深爱婷婷久久综合一区| 黄网站色欧美视频| 日韩欧美国产一区二区| 国产精品久久久久久久久久小说| 91国产高清在线| 国产视频自拍一区| 日韩av手机在线看| 欧美www视频在线观看| 91成人性视频| 国产精品青草久久久久福利99| 亚洲精品视频中文字幕| 日韩精品高清在线观看| 久久久久久久久久久成人| 亚洲精品久久久久久久久久久| 久久国产精品久久久久久久久久| 欧美午夜激情在线| 精品国产一区久久久| 欧美在线视频在线播放完整版免费观看| 不卡在线观看电视剧完整版| 国产精品免费久久久久久| 欧美电影免费观看电视剧大全| 欧美影院久久久| 中文字幕亚洲无线码在线一区| 精品久久久久久中文字幕一区奶水| 少妇高潮久久77777| 欧美精品18videosex性欧美| 亚洲电影免费观看高清| 国产不卡一区二区在线播放| 亚洲精品小视频在线观看| 情事1991在线| 国产精品麻豆va在线播放| 一区二区三区四区在线观看视频| 国产欧美日韩综合精品| 亚洲电影免费观看高清| 亚洲综合在线播放| 国产精品久久久精品| 亚洲视频在线观看网站| 欧美电影在线观看高清| 欧美精品手机在线| 亚洲欧美日本精品| 综合136福利视频在线| 久久人人看视频| 富二代精品短视频| 久久久中精品2020中文| 欧美www视频在线观看| 国产精品美乳一区二区免费| 欧美乱大交xxxxx另类电影| 日韩av免费一区|