記錄一下cocos2dx中記憶體管理的理解和試驗
一直弄c++的,還經常到底層晃蕩滴,十分不習慣記憶體這麼寶貴的資源不受自己控制的程式設計,就像大熱天坐在電腦前打遊戲,邊上千把只蚊子飛來飛去一樣難受。尤其是那個autorelease,大把的兄弟們分析了它的排隊和刪除機制了,但私心裡總想,自己造出來的東西,為毛不能我想讓它滾蛋就滾蛋,總在記憶體裡掛著作甚。雖然autorelease這種機制確實有它的優點,但也沒必要到處都用吧……,手機記憶體現在也不便宜啊。
一、我們的目標
c++的方式一般是new、delete成對用,我們的目標也就是這個,告別靜態方法,告別 create_func巨集,告別autorelease retain release,重要的是,autorelease的佇列中不要加入我們不想加入的東西。
二、一點點摘吧出來
#include "gamescene.h"
gamescene::gamescene(void)
gamescene::~gamescene(void)
void gamescene::initlayer()
首先裝模作樣的管理一下記憶體,一般來說,cocos2dx如此打包的原因估計就是想讓記憶體管理更加簡單,於是推著大夥使用靜態create方法,在這個方法中,實際使用new例項了物件,並且隨後呼叫autorelease將其排隊了。通常我們不用retain和release,因為一般大夥兒把這貨造出來都是為了addchild的,在addchild裡面實際做了一次retain,然後在使用結束的某個地方removechild的時候(沒去找,可能是析構,又release了一下)。我們在這裡試圖讓autorelease失去作用,於是構造時retain一下,析構時release一下,基本做到我想放的時候放,當然不一定掉了)
其次是避免使用靜態create方法。 }
// initialize director
auto director = director::getinstance();
auto glview = director->getopenglview();
if(!glview)
// turn on display fps
director->setdisplaystats(true);
// set fps. the default value is 1.0/60 if you don't call this
director->setanimationinterval(1.0 / 60);
// create a scene. it's an autorelease object
auto gamescene = scene::create();
gamescene->addchild(pmainlayer);
pmainlayer = new gamescene();
pmainlayer->initlayer();
director->runwithscene(gamescene);
return true;}
那麼,顯然現在我們要管理如何放掉它了。如某些同學的說法,可以講new和release對起來用,一開始我就是這麼用的(注釋中的內容),但實際情況是,直接用delete好了。現在看起來很像c++了吧,哈哈。
三、sprite為什麼沒有用new、delete?
可能有兄弟已經注意到,sprite,這個最需要我們精細管理的物件這裡並沒有使用new、delete。確實,一開始我想用來著,先new乙個sprite,然後用initwithfile載入,就像靜態方法create一樣。但是編譯器不幹,為什麼呢?
/// @}
cc_constructor_access:
sprite(void);
virtual ~sprite(void);
/* initializes an empty sprite with nothing init. */
virtual bool init(void);
/*** initializes a sprite with a texture.
** after initialization, the rect used will be the size of the texture, and the offset will be (0,0).
** @param texture a pointer to an existing texture2d object.
* you can use a texture2d object for many sprites.
* @return true if the sprite is initialized properly, false otherwise.
*/virtual bool initwithtexture(texture2d *texture);
看看ccsprite的原始碼就知道了,cc_constructor_access其實就是protect換張皮,換句話說,cocos2dx將new、delete保護起來了,不讓用,必須autorelease。可以想見,layer必然也是,那上面的layer為什麼可以?對了,只要繼承一下就行了,此時記憶體完全由我掌控。
四、是不是有點作?
可能真是有點作吧,俗話說no zuo no die,可能有一天碰上莫名其妙的問題就是如此作出來的,所以立文為證,提醒自己一下。畢竟還是用慣了new、delete和自己親力親為的管理,強迫症使然,乙個不用自己管的記憶體扔在那裡總覺得這玩意指定洩露了。決定以後如此new、delete的來了,會不會有蝦公尺問題?有木有高手指點一下?
五、現實報來得快
這兩天搬家整房子,手頭停了一段。今天撿起來按照前面「作」的內容完整的寫下來才發現,原來還不僅僅是new delete受protect限制的問題,還有函式initwithfile,沒辦法,繼承類裡面加個公開函式包一下吧,這樣外面就可以呼叫了。如何,下面這個是不是看起來舒服多了?如果還覺得不爽,過載個建構函式吧init替了吧,不過這樣就只能assert initwithfile返回true了。
哈哈,首先解決個人習慣問題,後面爬起**來才會爽。
//初始化opengl
auto director = director::getinstance();
auto glview = director->getopenglview();
if(!glview)
// turn on display fps
director->setdisplaystats(true);
// set fps. the default value is 1.0/60 if you don't call this
director->setanimationinterval(1.0 / 60);
//建立場景,場景是自釋放的物件
scene* gamescene = scene::createwithphysics();
//遊戲主介面層
pmainlayer = new gamelayer();
gamescene->addchild(pmainlayer);
//pmainlayer->initlayer();
director->runwithscene(gamescene);
return true;
}//gamelayer繼承自layer
gamelayer::gamelayer(void)
gamelayer::~gamelayer(void)
//lrole繼承自sprite
lrole::lrole(void)
lrole::~lrole(void)
bool lrole::init(const string& filename)
cocos2d x記憶體優化
程式包的 體積 優化方法 首先 你需要很清楚當前自己專案什麼地方佔的體積最多,例如動畫序列多少mb 地圖佔多少mb等等,都要提前做乙個check 別總是認為 可能佔的多,要詳細的知道才行!1.採用工具對資源進行 打包 例如texturepacker 等工具。2.採用png壓縮工具等,在打包前對每張進...
cocos2dx 記憶體管理
記憶體管理中經常遇到的問題 記憶體洩露,記憶體溢位。在cocos2dx中用的是引用計數和自動釋放池的技術,由於熟悉objective c語言,所以對這兩個概念不會很陌生。一 引用計數 引用計數是自動記憶體管理的基礎 在物件裡增加乙個引用計數,當外部引用增加時,計數器加1,當外部引用消失時,計數器減1...
cocos2d x 記憶體管理
呼叫了autorelease的物件,將會在自動 池釋放的時候被釋放一次。因為這個操作發生在 mainloop drawscene 後,這時候遊戲中所有的邏輯已經執行完畢,正是釋放無效資源的最佳時機。所以乙個物件被create後,將被放進pool中,其ref 數為1,當遊戲整個邏輯跑完,如果沒有增加r...