日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【深入Cocos2d-x】探索Cocos2d-x中的内存管理-引用计数和自动释放池

發布時間:2025/3/17 编程问答 12 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【深入Cocos2d-x】探索Cocos2d-x中的内存管理-引用计数和自动释放池 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

#深入Cocos2d-x-探索Cocos2d-x中的內存管理-引用計數和自動釋放池

###引用計數(Reference Count)

引用計數是一種在C++中相當古老的內存管理方法,ios中將這種機制包括在NSAutoreleasePool中。所有我們在Cocos2d-x中也有個相似的東西,叫CCAutoreleasePool,用處基本上一樣,詳細請看:NSAutoreleasePool Class Reference

###CCAutoRealeasePool

CCAutoRealeasePool與NSAutoreleasePool有著相同的概念和架構,但有兩個重要區別:

  • CCAutoreleasePool不能嵌套,所以每個cocoss2d-x的游戲實例中僅能有一個,開發者不能創建新的CCAutoreleasePool,而只是注意CCOject的釋放和增加引用計數(realease/retain)就可以了
  • CCAutoreleasePool不能在多線程中使用 。所以如果你的游戲需要一個網絡線程,請僅僅接收數據或者改變網絡中的狀態值,不要調用其中的Cocos2d接口。
  • 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()

    總而言之,有兩種情況你需要調用 ->realease()方法

  • 當你通過new的方式創建一個CCObject時
  • 當你得到一個CCObject的指針,然后在代碼里調用“retain”方法
  • 下面是一個例子,他不需要realease()

    CCSprite* sprite = CCSprite::create("player.png");

    如果你看了源碼的話,你會發現在create方法里CCSprite已經調用了autorealease

    ###使用靜態構造方法

    CCSprite::create("player.png") 就是用了靜態構造方法. 在Cocos2d-x中的所有類, 除了單件, 都提供了這種create方法,在其中包含了四個操作:

  • new an object
  • call object->init(...)
  • if init success, e.g. find the texture file successfully, it will call object->autorelease();
  • return the object marked as autorelease.
  • 所有的 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

    翻譯原文請點擊這里

    轉載于:https://my.oschina.net/wangxuanyihaha/blog/133787

    總結

    以上是生活随笔為你收集整理的【深入Cocos2d-x】探索Cocos2d-x中的内存管理-引用计数和自动释放池的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。