现在的位置: 首页 > 综合 > 正文

cocos2d-x精灵内存管理

2014年01月15日 ⁄ 综合 ⁄ 共 3799字 ⁄ 字号 评论关闭
 1bool HelloWorld::init()
 2{
 3    bool bRet = false;
 4    do
 5    {
 6        //////////////////////////////////////////////////////////////////////////
 7        // super init first
 8        //////////////////////////////////////////////////////////////////////////
 9
10        CC_BREAK_IF(! CCLayer::init());
11
12        //////////////////////////////////////////////////////////////////////////
13        // add your codes below...
14        //////////////////////////////////////////////////////////////////////////
15
16        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");
22
23        addChild(bomb1,1);
24        addChild(bomb2,1);
25        addChild(bomb3,1);
26        addChild(bomb4,1);
27        addChild(bomb5,1);
28        addChild(bomb6,1);
29
30  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()
33
34        this->scheduleUpdate();
35
36        bRet = true;
37    } while (0);
38
39    return bRet;
40}
41
42void HelloWorld::update(ccTime dt)
43{
44    refreshData();
45}
46
47void HelloWorld::refreshData()
48{
49    m_pBombsDisplayed->objectAtIndex(0)->setPosition(cpp(100,100));
50}

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

跟踪addChild函数可以看到

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

void CCNode::insertChild(CCNode* child, int z)
{
    m_bReorderChildDirty = true;
    ccArrayAppendObjectWithResize(m_pChildren->data, child); //重点,初始化children数组
    child->_setZOrder(z);
}

进入ccArrayAppendObjectWithResize

void ccArrayAppendObjectWithResize(ccArray *arr, CCObject* object)
{
	ccArrayEnsureExtraCapacity(arr, 1);
	ccArrayAppendObject(arr, object); //重点
}

进入ccArrayAppendObject

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的析构函数

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的释放会调用到

/** 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

/** 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被释放

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

抱歉!评论已关闭.