cocos2d-x精灵内存管理

来源:互联网 发布:二元期权模拟软件 编辑:程序博客网 时间:2024/04/30 21:39

转自:http://blog.csdn.net/qq276592716/article/details/12970623

 

[cpp] view plaincopyprint?
  1.  1bool HelloWorld::init()  
  2.  2{  
  3.  3    bool bRet = false;  
  4.  4    do  
  5.  5    {  
  6.  6        //////////////////////////////////////////////////////////////////////////  
  7.  7        // super init first  
  8.  8        //////////////////////////////////////////////////////////////////////////  
  9.  9  
  10. 10        CC_BREAK_IF(! CCLayer::init());  
  11. 11  
  12. 12        //////////////////////////////////////////////////////////////////////////  
  13. 13        // add your codes below...  
  14. 14        //////////////////////////////////////////////////////////////////////////  
  15. 15  
  16. 16        CCSprite* bomb1 = CCSprite::create("CloseNormal.png");  
  17. 17        CCSprite* bomb2 = CCSprite::create("CloseNormal.png");  
  18. 18        CCSprite* bomb3 = CCSprite::create("CloseNormal.png");  
  19. 19        CCSprite* bomb4 = CCSprite::create("CloseNormal.png");  
  20. 20        CCSprite* bomb5 = CCSprite::create("CloseNormal.png");  
  21. 21        CCSprite* bomb6 = CCSprite::create("CloseNormal.png");  
  22. 22  
  23. 23        addChild(bomb1,1);  
  24. 24        addChild(bomb2,1);  
  25. 25        addChild(bomb3,1);  
  26. 26        addChild(bomb4,1);  
  27. 27        addChild(bomb5,1);  
  28. 28        addChild(bomb6,1);  
  29. 29  
  30. 30  m_pBombsDisplayed= CCArray::create(bomb1,bomb2,bomb3,bomb4,bomb5,bomb6,NULL);  
  31. 31        //m_pBombsDisplayed is defined in the header as a protected var.  
  32. 32        // <--- We should add m_pBombsDisplayed->retain() here to avoid crashing in           
  33.              HelloWorld::refreshData()  
  34. 33  
  35. 34        this->scheduleUpdate();  
  36. 35  
  37. 36        bRet = true;  
  38. 37    } while (0);  
  39. 38  
  40. 39    return bRet;  
  41. 40}  
  42. 41  
  43. 42void HelloWorld::update(ccTime dt)  
  44. 43{  
  45. 44    refreshData();  
  46. 45}  
  47. 46  
  48. 47void HelloWorld::refreshData()  
  49. 48{  
  50. 49    m_pBombsDisplayed->objectAtIndex(0)->setPosition(cpp(100,100));  
  51. 50}  
 1bool HelloWorld::init() 2{ 3    bool bRet = false; 4    do 5    { 6        ////////////////////////////////////////////////////////////////////////// 7        // super init first 8        ////////////////////////////////////////////////////////////////////////// 910        CC_BREAK_IF(! CCLayer::init());1112        //////////////////////////////////////////////////////////////////////////13        // add your codes below...14        //////////////////////////////////////////////////////////////////////////1516        CCSprite* bomb1 = CCSprite::create("CloseNormal.png");17        CCSprite* bomb2 = CCSprite::create("CloseNormal.png");18        CCSprite* bomb3 = CCSprite::create("CloseNormal.png");19        CCSprite* bomb4 = CCSprite::create("CloseNormal.png");20        CCSprite* bomb5 = CCSprite::create("CloseNormal.png");21        CCSprite* bomb6 = CCSprite::create("CloseNormal.png");2223        addChild(bomb1,1);24        addChild(bomb2,1);25        addChild(bomb3,1);26        addChild(bomb4,1);27        addChild(bomb5,1);28        addChild(bomb6,1);2930  m_pBombsDisplayed= CCArray::create(bomb1,bomb2,bomb3,bomb4,bomb5,bomb6,NULL);31        //m_pBombsDisplayed is defined in the header as a protected var.32        // <--- We should add m_pBombsDisplayed->retain() here to avoid crashing in              HelloWorld::refreshData()3334        this->scheduleUpdate();3536        bRet = true;37    } while (0);3839    return bRet;40}4142void HelloWorld::update(ccTime dt)43{44    refreshData();45}4647void HelloWorld::refreshData()48{49    m_pBombsDisplayed->objectAtIndex(0)->setPosition(cpp(100,100));50}

1.上面的bomb精灵在函数结束后是否会释放?

跟踪addChild函数可以看到

[cpp] view plaincopyprint?
  1. void CCNode::addChild(CCNode *child, int zOrder, int tag)  
  2. {      
  3.     CCAssert( child != NULL, "Argument must be non-nil");  
  4.     CCAssert( child->m_pParent == NULL, "child already added. It can't be added again");  
  5.   
  6.     if( ! m_pChildren )//构造children数组  
  7.     {  
  8.         this->childrenAlloc();  
  9.     }  
  10.   
  11.     this->insertChild(child, zOrder);  //重点  
  12.   
  13.     child->m_nTag = tag;  
  14.   
  15.     child->setParent(this);  
  16.     child->setOrderOfArrival(s_globalOrderOfArrival++);  
  17.   
  18.     if( m_bRunning )  
  19.     {  
  20.         child->onEnter();  
  21.         child->onEnterTransitionDidFinish();  
  22.     }  
  23. }  
void CCNode::addChild(CCNode *child, int zOrder, int tag){        CCAssert( child != NULL, "Argument must be non-nil");    CCAssert( child->m_pParent == NULL, "child already added. It can't be added again");    if( ! m_pChildren )//构造children数组    {        this->childrenAlloc();    }    this->insertChild(child, zOrder);  //重点    child->m_nTag = tag;    child->setParent(this);    child->setOrderOfArrival(s_globalOrderOfArrival++);    if( m_bRunning )    {        child->onEnter();        child->onEnterTransitionDidFinish();    }}

进入insertChild

[cpp] view plaincopyprint?
  1. void CCNode::insertChild(CCNode* child, int z)  
  2. {  
  3.     m_bReorderChildDirty = true;  
  4.     ccArrayAppendObjectWithResize(m_pChildren->data, child); //重点,初始化children数组  
  5.     child->_setZOrder(z);  
  6. }  
void CCNode::insertChild(CCNode* child, int z){    m_bReorderChildDirty = true;    ccArrayAppendObjectWithResize(m_pChildren->data, child); //重点,初始化children数组    child->_setZOrder(z);}

进入ccArrayAppendObjectWithResize

[cpp] view plaincopyprint?
  1. void ccArrayAppendObjectWithResize(ccArray *arr, CCObject* object)  
  2. {  
  3.     ccArrayEnsureExtraCapacity(arr, 1);  
  4.     ccArrayAppendObject(arr, object); //重点  
  5. }  
void ccArrayAppendObjectWithResize(ccArray *arr, CCObject* object){ccArrayEnsureExtraCapacity(arr, 1);ccArrayAppendObject(arr, object); //重点}

进入ccArrayAppendObject

[cpp] view plaincopyprint?
  1. void ccArrayAppendObject(ccArray *arr, CCObject* object)  
  2. {  
  3.     CCAssert(object != NULL, "Invalid parameter!");  
  4.     object->retain();   //真相大白  
  5.     arr->arr[arr->num] = object;  
  6.     arr->num++;  
  7. }  
void ccArrayAppendObject(ccArray *arr, CCObject* object){    CCAssert(object != NULL, "Invalid parameter!");    object->retain();   //真相大白arr->arr[arr->num] = object;arr->num++;}

ccArrayAppendObject里面进行了引用计数的+1,使得在函数结束后对象不会被自动回收。


2.上面的bomb精灵在什么时候释放?

见ccnode的析构函数

[cpp] view plaincopyprint?
  1. CCNode::~CCNode(void)  
  2. {  
  3.     CCLOGINFO( "cocos2d: deallocing" );  
  4.       
  5.     unregisterScriptHandler();  
  6.     if (m_nUpdateScriptHandler)  
  7.     {  
  8.         CCScriptEngineManager::sharedManager()->getScriptEngine()->removeScriptHandler(m_nUpdateScriptHandler);  
  9.     }  
  10.   
  11.     CC_SAFE_RELEASE(m_pActionManager);  
  12.     CC_SAFE_RELEASE(m_pScheduler);  
  13.     // attributes  
  14.     CC_SAFE_RELEASE(m_pCamera);  
  15.   
  16.     CC_SAFE_RELEASE(m_pGrid);  
  17.     CC_SAFE_RELEASE(m_pShaderProgram);  
  18.     CC_SAFE_RELEASE(m_pUserObject);  
  19.   
  20.     if(m_pChildren && m_pChildren->count() > 0)  
  21.     {  
  22.         CCObject* child;  
  23.         CCARRAY_FOREACH(m_pChildren, child)  
  24.         {  
  25.             CCNode* pChild = (CCNode*) child;  
  26.             if (pChild)  
  27.             {  
  28.                 pChild->m_pParent = NULL;  
  29.             }  
  30.         }  
  31.     }  
  32.   
  33.     // children  
  34.     CC_SAFE_RELEASE(m_pChildren);  //这边,降低m_pChildren的引用计数,使其释放  
  35.       
  36.           // m_pComsContainer  
  37.     m_pComponentContainer->removeAll();  
  38.     CC_SAFE_DELETE(m_pComponentContainer);  
  39. }  
CCNode::~CCNode(void){    CCLOGINFO( "cocos2d: deallocing" );        unregisterScriptHandler();    if (m_nUpdateScriptHandler)    {        CCScriptEngineManager::sharedManager()->getScriptEngine()->removeScriptHandler(m_nUpdateScriptHandler);    }    CC_SAFE_RELEASE(m_pActionManager);    CC_SAFE_RELEASE(m_pScheduler);    // attributes    CC_SAFE_RELEASE(m_pCamera);    CC_SAFE_RELEASE(m_pGrid);    CC_SAFE_RELEASE(m_pShaderProgram);    CC_SAFE_RELEASE(m_pUserObject);    if(m_pChildren && m_pChildren->count() > 0)    {        CCObject* child;        CCARRAY_FOREACH(m_pChildren, child)        {            CCNode* pChild = (CCNode*) child;            if (pChild)            {                pChild->m_pParent = NULL;            }        }    }    // children    CC_SAFE_RELEASE(m_pChildren);  //这边,降低m_pChildren的引用计数,使其释放              // m_pComsContainer    m_pComponentContainer->removeAll();    CC_SAFE_DELETE(m_pComponentContainer);}

CCARRAY的释放会调用到

[cpp] view plaincopyprint?
  1. /** Frees array after removing all remaining objects. Silently ignores NULL arr. */  
  2. void ccArrayFree(ccArray*& arr)  
  3. {  
  4.     if( arr == NULL )   
  5.     {  
  6.         return;  
  7.     }  
  8.     ccArrayRemoveAllObjects(arr);  
  9.       
  10.     free(arr->arr);  
  11.     free(arr);  
  12.   
  13.     arr = NULL;  
  14. }  
/** Frees array after removing all remaining objects. Silently ignores NULL arr. */void ccArrayFree(ccArray*& arr){    if( arr == NULL )     {        return;    }ccArrayRemoveAllObjects(arr);free(arr->arr);free(arr);    arr = NULL;}

进入ccArrayRemoveAllObjects

[cpp] view plaincopyprint?
  1. /** Removes all objects from arr */  
  2. void ccArrayRemoveAllObjects(ccArray *arr)  
  3. {  
  4.     while( arr->num > 0 )  
  5.     {  
  6.         (arr->arr[--arr->num])->release();  //每个元素的引用计数-1,使其释放  
  7.     }  
  8. }  
/** Removes all objects from arr */void ccArrayRemoveAllObjects(ccArray *arr){while( arr->num > 0 )    {(arr->arr[--arr->num])->release();  //每个元素的引用计数-1,使其释放    }}

3.上面的m_pBombsDisplayed会在什么时候释放?

  见CCARRAYcreate函数,create后引用计数为1,在函数结束后-1为0被释放

[cpp] view plaincopyprint?
  1. CCArray* CCArray::create()  
  2. {  
  3.     CCArray* pArray = new CCArray();  
  4.   
  5.     if (pArray && pArray->init())  
  6.     {  
  7.         pArray->autorelease(); //放入了autorelease里面,引用计数在函数结束自动-1,被回收。  
  8.     }  
  9.     else  
  10.     {  
  11.         CC_SAFE_DELETE(pArray);  
  12.     }  
  13.       
  14.     return pArray;  
  15. }  
CCArray* CCArray::create(){    CCArray* pArray = new CCArray();    if (pArray && pArray->init())    {        pArray->autorelease(); //放入了autorelease里面,引用计数在函数结束自动-1,被回收。    }    else    {        CC_SAFE_DELETE(pArray);    }        return pArray;}

4.解决m_pBombsDisplayed的问题,主动retain,在helloworld析构的时候release