1.cocos2dx内存管理和CCArray,CCMenuItem
1 C++內存管理
| A 棧上的空間 |
| 自生自滅,不用管理 |
| B 堆上的空間 |
| 手動new,手動delete,否則產生內存泄漏 |
2 內存管理的難處
| 管理原則,誰申請誰釋放 |
3 內存的智能管理
主要有兩種實現智能管理內存的技術,一種是引用計數,一是垃圾回收。
引用計數:通過給每個對象維護一個引用計數器,記錄該對象當前被引用的次數。當對象增加一次引用時,計數器加1;而對象失去一次引用時,計數器減1;當引用計數為0 時,標志著該對象的生命周期結束,自動觸發對象的回收釋放。引用計數解決了對象的生命周期管理問題,但堆碎片化和管理煩瑣的問題仍然存在。
??? 垃圾回收:它通過引入一種自動的內存回收器,試圖將程序員從復雜的內存管理任務中完全解放出來。它會自動跟蹤每一個對象的所有引用,以便找到所有正在使用的對象,然后釋放其余不再需要的對象。垃垃圾回收器通常是作為一個單獨的低級別的線程運行的,在不可預知的情況下對內存堆中已經死亡的或者長時間沒有使用過的對象進行清除和回收。
4 cocos2dx內存管理
A 手動管理
Cocos2dx采用工廠方法創建對象,所有生成的對象均在堆上,所以Cocos2dx采用了引用計數的方法管理內存。具體實現:
B?? 案例說明:
| T09Memory.h |
| #ifndef _T09Memory_ #define _T09Memory_ ? #include "cocos2d.h" USING_NS_CC; class T09Memory :public CCLayer { public: ??? static CCScene * scene(); ??? CREATE_FUNC(T09Memory); ??? bool init(); ??? ??? CCSprite * spr; ??? void mySchedule(float dt); }; ? #endif |
| T09Memory.cpp |
| #include "T09Memory.h" ? CCScene * T09Memory::scene() { ??? CCScene *scene = CCScene::create(); ??? T09Memory *layer = T09Memory::create(); ??? scene->addChild(layer); ??? return scene; } ? bool T09Memory::init() { ??? CCLayer::init(); ? ??? spr = new CCSprite(); ??? //CCLog("retain count %d", spr->retainCount()); ??? spr->retain(); //引用計數加1 ??? CCLog("use spr->retatin : retain count %d", spr->retainCount()); ??? //spr->release(); ??? //CCLog("retain count %d", spr->retainCount()); ? ??? spr->init(); ??? spr->release(); ? ??? //autorelease()也release了但是不一定就釋放了,而是遵循延時釋放 ??? spr->autorelease();??? //延時釋放 ??? //CCLog("retain count %d", spr->retainCount()); ??? addChild(spr);?? //這里引用,這里引用加1 ??? CCLog("retain count %d", spr->retainCount()); ? ??? //通過下面可以證明上面已經釋放內存了 ??? schedule(schedule_selector(T09Memory::mySchedule),2); ??? return true; } ? void T09Memory::mySchedule(float dt) { ??? CCLog("retain count %d", spr->retainCount()); } |
| 運行結果:
|
C ?retain()本質
D? autorelease()本質(延遲釋放內存)
5 CCArray
A 類關系圖
B ?CCArray繼承自CCObject,而非CCNode,沒有辦法加到渲染樹中去,但是參加了內存托管。所以應該手動處理。
示例:
| Array = CCArray::create(); Array->retain(); CCSprite *spr = CCSprite::create(); array->addObject(spr); CCMenuItem *item = CCMenuItemImage::create(“closeNormal.png” “CloseSelected.png”, this, menu_selector(T09Memory::menuCallBack) ); CCMenu * menu = CCMenu::create(item,NULL); ??? addChild(menu); |
| Void T09Memory::menuCallBack(CCObject *obj){ ??? //獲得array中的第一個值 ??? array->objectAtIndex(0); } |
C? 例外中的例外
| void T09Memory::onExit(){ ??? array->release(); } |
C CCArray的案例:
| T09Memory.h |
| #ifndef __T09Memory_H__ #define __T09Memory_H__ ? #include "cocos2d.h" USING_NS_CC; class T09Memory :public CCLayer { public: ??? static CCScene * scene(); ??? CREATE_FUNC(T09Memory); ??? bool init(); ? ??? CCSprite * spr; ??? void menuCallback(CCObject * obj); ? ??? CCArray *array; ? ??? void onExit(); }; ? #endif |
| T09Memory.cpp |
| #include "T09Memory.h" ? CCScene * T09Memory::scene() { ??? CCScene *scene = CCScene::create(); ??? T09Memory *layer = T09Memory::create(); ??? scene->addChild(layer); ??? return scene; } ? bool T09Memory::init() { ??? CCLayer::init(); ??? array = CCArray::create(); ??? array->retain(); ??? spr = CCSprite::create("CloseNormal.png"); ??? CCSprite * spr2 = CCSprite::create("p_3_01.png"); ??? array->addObject(spr); ??? array->addObject(spr2); ??? //添加一個精靈 ??? addChild(spr); ? ??? //通過下面的方式實現鼠標點擊上去后圖片切換的效果 ??? CCMenuItem * item = CCMenuItemImage::create( ??????? "CloseNormal.png", ??????? "CloseSelected.png", ??????? this, ??????? menu_selector(T09Memory::menuCallback)); ? ??? CCMenu * menu = CCMenu::create(item, NULL); ??? //添加CCMenuItem條項 ??? addChild(menu); ? ??? return true; } ? void T09Memory::menuCallback(CCObject * obj) { ??? array->objectAtIndex(0); ??? //下面的一句將CCArray中的第二個參數去除來了 ??? CCSprite * spr = (CCSprite *)array->objectAtIndex(1); ??? spr->setPosition(ccp(100,200)); ??? addChild(spr); } ? //在層退出的時候調用 void T09Memory::onExit() { ??? //降引用計數減1 ??? array->release(); } |
| 運行結果: 點擊前:
點擊后:
|
?
?
?
?
?
總結
以上是生活随笔為你收集整理的1.cocos2dx内存管理和CCArray,CCMenuItem的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 农业银行白金卡办理条件
- 下一篇: 2.标签CCLabelTTF,CCLab