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。