转自:http://blog.csdn.net/qq276592716/article/details/12970623
- 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}
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();
- }
- }
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);
- }
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); //重点
- }
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++;
- }
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);
- }
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;
- }
/** 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,使其释放
- }
- }
/** 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;
- }
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。