CocoStudio确实存在太多内存泄露。今天刚好修复了这方面的BUG,在这里和大家分享一下。
内存泄露的地方主要存在于几个方面
1.骨骼动画里面的一些静态指针。比如cs:: DisplayFactoryManager:: g_DisplayFactoryMap,cs:: DataReaderHelper:: m_pJson,cs:: Armature:: m_sArmatureMap
2.一些单例模式。CCSReader::shareReader(),DictionaryHelper::shareHelper(),UISystem::shareSystem()。
3.CCSReader::widgetFromJson**方法里面的一些Json相关的对象没有delete。主要在:widgetFromJsonDictionary和widgetFromJsonFile方法里面。
4.在CocoWidget::addChild()代码错误导致的内存泄露。当添加的Child的Zorder是已经添加的数组里面的最小一个时,该CocoWidget不能正确被添加到CocoWidget::m_children里面,但是addChildNode(child);可以正常工作,导致这个错误变得很隐晦,因为这个Widget可以在界面里面正常显示。但是你他却不是任何一个widget的孩子。但是这和内存泄露有什么关系了?听我慢慢道来:P。
UISystem::cleanUIScene()最终会调用到CocoWidget::removeAllChildrenAndCleanUp(bool cleanup)方法。而这个方法是不断的删除自己的孩子并且释放他们的资源同时delete掉这个孩子对象。所以由于这个孩子没有被添加到数组里面。导致这个孩子不能被正确释放。这时候有同学会说了,既然没有加入这个数组,那么这个孩子就没人引用,根据自动内存释放的原则,这个孩子会在下一帧里面被自动释放掉。想法是对的。但是如果你去查看CocoWidget以及它的子类的create()方法,你会发现他们都是没有调用autorelease()的。所以自动内存释放是无效的。这是一个比较隐晦的错误。这也是你使用UI编辑工具编辑的界面,某些控件无法通过COCOUISYSTEM->checkWidgetByName()找到的原因。因为他们根本没有成功的添加到children数组里面。
附上我的内存释放方法:
UISystem::~UISystem()
{
cs::DisplayFactoryManager::g_DisplayFactoryMap->removeAllObjects();
CC_SAFE_DELETE(cs::DisplayFactoryManager::g_DisplayFactoryMap);
cs::DataReaderHelper::m_pJson->cleanUp();
CC_SAFE_DELETE(cs::DataReaderHelper::m_pJson);
cs::Armature::m_sArmatureMap->removeAllObjects();
CC_SAFE_DELETE(cs::Armature::m_sArmatureMap);
cleanUIScene();
CC_SAFE_DELETE(m_pCurScene);
m_textureFiles->removeAllObjects();
CC_SAFE_RELEASE(m_textureFiles);
CC_SAFE_DELETE(m_pUIInputManager);
delete (CCSReader::shareReader());
delete (DictionaryHelper::shareHelper());
sharedSystem = NULL;
}
AppDelegate::~AppDelegate()
{
SimpleAudioEngine::end();
delete COCOUISYSTEM;
}
在WIN32下使用vld检测已经没有内存泄露。可能写法不是很标准,还望各位指正。