記錄一下Cocos2dX中記憶體管理的理解和試驗

2021-06-21 22:24:44 字數 3961 閱讀 1024

記錄一下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...