声明:该改造未经过严格的测试,本文属于个人备忘。如参考本文引起的问题,本人概不负责。当然欢迎大家批评指导!
1. CCObject.h
加入类的名字,方便调试的时候在基类中识别派生类。
private:
char name_[16]; // 注意要初始化
public:
inline void set_name(constchar* _name){strncpy(name_, _name,16);}
inline const char* get_name(){ return name_; }
然后在ccplateformmacros.h中将CREATE_FUNC 加上一行代码
pRet->set_name(#__TYPE__); \
// release 方法源代码
// CCAssert(m_uReference > 0, "reference count should greater than 0");
// 现在的代码修改为
if (m_uReference <= 0)
{
CCLOG("release,%d,%p,%s,reference count should greater than 0!!!!",
m_uReference, this, this->get_name());
}
2. CCNode.cpp
cleanup(),removechild(),detachChild() 加入以下代码,避免对对象的过度释放引发crash
if(child->retainCount() <= 0)
{
CCLog("[%s:%d] retainCount(%d),classname(%s)",__FILE__,__LINE__, child->retainCount(),child->get_name()); return; }
3.CCNode.h
将setZOrder该为public,只是为了方便。
4. CCDirector.cpp
为了节省内存将sharedSpriteFrameCache也进行了释放。目前没有观察到问题
void CCDirector::purgeCachedData(void)
{
CCLabelBMFont::purgeCachedData();
CCTextureCache::sharedTextureCache()->removeUnusedTextures();
CCFileUtils::sharedFileUtils()->purgeCachedEntries();
}
修改为
void CCDirector::purgeCachedData(void)
{
CCLabelBMFont::purgeCachedData();
CCSpriteFrameCache::sharedSpriteFrameCache()->removeUnusedSpriteFrames(); // add
CCTextureCache::sharedTextureCache()->removeUnusedTextures();
//CCFileUtils::sharedFileUtils()->purgeCachedEntries(); ?? memory leak?
}
5. CCArray.h
arrayMakeObjectsPerformSelector加个容错,避免程序crash。
#define arrayMakeObjectsPerformSelector(pArray, func, elementType) \
do { \
if(pArray && pArray->data && pArray->count() > 0) \
{ \
CCObject* child; \
CCARRAY_FOREACH(pArray, child) \
{ \
elementType pNode = (elementType) child; \
if(pNode) \
{ \
pNode->func(); \
} \
} \
} \
} \
while(false)
6. CCPoolManager.cpp
void CCPoolManager::pop()
{
...
int nCount = m_pReleasePoolStack->count();
m_pCurReleasePool->clear();
if(nCount > 1)
{
m_pReleasePoolStack->removeObjectAtIndex(nCount-1);
m_pCurReleasePool = (CCAutoreleasePool*)m_pReleasePoolStack->objectAtIndex(nCount - 2);
}
}
修改为
m_pCurReleasePool->clear();
m_pCurReleasePool = NULL;
if(m_pReleasePoolStack->count() > 1)
m_pReleasePoolStack->removeObjectAtIndex(m_pReleasePoolStack->count()-1);
if(m_pReleasePoolStack->count() > 1)
m_pCurReleasePool = (CCAutoreleasePool*)m_pReleasePoolStack->objectAtIndex(m_pReleasePoolStack->count() - 1);
// 增加如下三个方法、可以手动的设置handler的优先级
void CCMenu::setHandlerPriorityNoError(int newPriority)
{
CCTouchHandler *handler = NULL;
handler = CCDirector::sharedDirector()->getTouchDispatcher()->findHandler(this);
if(handler == NULL)
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, newPriority, true);
else
this->setHandlerPriority(newPriority);
}
void CCMenu::setIsClarity(bool _isClarity)
{
isClarity = _isClarity;
}
bool CCMenu::getIsClarity()
{
return isClarity;
}
void CCMenu::registerWithTouchDispatcher()
{
CCTouchHandler *handler = CCDirector::sharedDirector()->getTouchDispatcher()->findHandler(this);
if(handler == NULL) // 这里加了容错
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, kCCMenuHandlerPriority, true);
}
// 修改容错
#define CC_SAFE_RELEASE(p) do { if(p && p->retainCount() >= 1) { (p)->release(); } } while(0)
#define CC_SAFE_RELEASE_NULL(p) do { if(p && p->retainCount() >= 1) { (p)->release(); (p) = 0; } } while(0)
if (hasAlpha && pixelFormat == kCCTexture2DPixelFormat_RGBA8888)
{
// Convert "RRRRRRRRRGGGGGGGGBBBBBBBBAAAAAAAA" to "RRRRRRRRGGGGGGGGBBBBBBBB"
inPixel32 = (unsigned int*)image->getData();
tempData = new unsigned char[width * height * 4];
unsigned char *outPixel8 = tempData;
for(unsigned int i = 0; i < length; ++i, ++inPixel32)
{
*outPixel8++ = (*inPixel32 >> 0) & 0xFF; // R
*outPixel8++ = (*inPixel32 >> 8) & 0xFF; // G
*outPixel8++ = (*inPixel32 >> 16) & 0xFF; // B
*outPixel8++ = (*inPixel32 >> 24) & 0xFF; // B
}
}