#深刻Cocos2d-x-探索Cocos2d-x中的內存管理-引用計數和自動釋放池html
###引用計數(Reference Count)ios
引用計數是一種在C++中至關古老的內存管理方法,ios中將這種機制包括在NSAutoreleasePool中。全部咱們在Cocos2d-x中也有個類似的東西,叫CCAutoreleasePool,用處基本上同樣,詳細請看:NSAutoreleasePool Class Referencejson
###CCAutoRealeasePoolapi
CCAutoRealeasePool與NSAutoreleasePool有着相同的概念和架構,但有兩個重要區別:網絡
CCAutoreleasePool的邏輯是這樣的:當你調用object->autorealease()這個方法時,這個object就被放在了CCAutoreleasePool中,這個計數池能幫你拿着這個object,想一個管家同樣的保存到當前message loop的結尾。等到了當前message loop的結尾若是這個object沒有被任何一個class或者container持有(retain)的話,它就被自動釋放出來。例如:layer->addChild(sprite),這個sprite被加到layer的children list中去,那麼它的生命週期就一直保持到這個layer被釋放的時候,而不是當前message loop的結尾就被釋放。多線程
因此啦,你就不能在網絡線程中管理CCObject啦:在每一個UI線程結束時,autorealease object就會被刪除掉,當你調用這些已經被刪除掉的對象的指針的話,game就會崩掉架構
###CCObject::release(), retain() and autorelease()app
總而言之,有兩種狀況你須要調用 ->realease()方法函數
下面是一個例子,他不須要realease()oop
CCSprite* sprite = CCSprite::create("player.png");
若是你看了源碼的話,你會發如今create方法裏CCSprite已經調用了autorealease
###使用靜態構造方法
CCSprite::create("player.png") 就是用了靜態構造方法. 在Cocos2d-x中的全部類, 除了單件, 都提供了這種create方法,在其中包含了四個操做:
全部的 CCAsdf::createWithXxxx(...) 類型的函數都™一個行爲
在使用create方法時,你不用考慮new,delete,autorealease之類的事,只要專一於這一對:object->retain() 和 object->release()
###一個錯誤的實例
一個開發者弄CCArray時弄崩了
<!-- lang: cpp --> bool HelloWorld::init() { bool bRet = false; do { ////////////////////////////////////////////////////////////////////////// // super init first ////////////////////////////////////////////////////////////////////////// CC_BREAK_IF(! CCLayer::init()); ////////////////////////////////////////////////////////////////////////// // add your codes below... ////////////////////////////////////////////////////////////////////////// CCSprite* bomb1 = CCSprite::create("CloseNormal.png"); CCSprite* bomb2 = CCSprite::create("CloseNormal.png"); CCSprite* bomb3 = CCSprite::create("CloseNormal.png"); CCSprite* bomb4 = CCSprite::create("CloseNormal.png"); CCSprite* bomb5 = CCSprite::create("CloseNormal.png"); CCSprite* bomb6 = CCSprite::create("CloseNormal.png"); addChild(bomb1,1); addChild(bomb2,1); addChild(bomb3,1); addChild(bomb4,1); addChild(bomb5,1); addChild(bomb6,1); m_pBombsDisplayed = CCArray::create(bomb1,bomb2,bomb3,bomb4,bomb5,bomb6,NULL); //m_pBombsDisplayed is defined in the header as a protected var. // <--- We should add m_pBombsDisplayed->retain() here to avoid crashing in HelloWorld::refreshData() this->scheduleUpdate(); bRet = true; } while (0); return bRet; } void HelloWorld::update(ccTime dt) { refreshData(); } void HelloWorld::refreshData() { m_pBombsDisplayed->objectAtIndex(0)->setPosition(cpp(100,100)); }
這哥們犯了什麼錯誤呢?m_pBombsDisplayed是由create方法建立的,他被標記爲autorealease,
因此在message loop結束時CCArray就被刪除了
當隨後的message loop調用 HelloWorld::update(ccTime)
時,m_pBombsDisplayed已是null了,因此解決辦法是在create方法後加上retain,在析構方法中加realease