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会在什么时候释放?
见CCARRAY的create函数,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。