【已解决】CocoStudio内存泄露解决方法

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检测已经没有内存泄露。可能写法不是很标准,还望各位指正。

以上问题,同求解决

bool CocoWidget::addChild(CocoWidget *child)
    {
        if (!child) {
            return false;
        }
        if (this->m_children->containsObject(child)) {
            return false;
        }
        child->m_pWidgetParent = this;
        int childrenCount = this->m_children->count();
        if (childrenCount <= 0) {
            this->m_children->addObject(child);
        }else{
            for (int i=childrenCount-1; i>=0; --i) {
                CocoWidget* widget = (CocoWidget*)(this->m_children->objectAtIndex(i));
        
bool CocoWidget::addChild(CocoWidget *child)
{
    if (!child) {
        return false;
    }
    if (this->m_children->containsObject(child)) {
        return false;
    }
    child->m_pWidgetParent = this;
    int childrenCount = this->m_children->count();
    if (childrenCount <= 0) {
        this->m_children->addObject(child);
    }else{
        for (int i=childrenCount-1; i>=0; --i) {
            CocoWidget* widget = (CocoWidget*)(this->m_children->objectAtIndex(i));
			//BUG:如果新添加的child的zOrder比m_children里任何widget都小的话,就无法把child添加进m_children里,但却可以加入节点系统里
            if (child->getWidgetZOrder() >= widget->getWidgetZOrder()) {
                if (i == childrenCount-1) {
                    this->m_children->addObject(child);
                    break;
                }else{
                    this->m_children->insertObject(child, i+1);
                    break;
                }
            }
        }
    }
    this->addChildNode(child);
    this->activeToUIInputManager();
    return true;
}
if (child->getWidgetZOrder() >= widget->getWidgetZOrder()) {
                    if (i == childrenCount-1) {
                        this->m_children->addObject(child);
                        break;
                    }else{
                        this->m_children->insertObject(child, i+1);
                        break;
                    }
                }
            }
        }
        this->addChildNode(child);
        this->activeToUIInputManager();
        return true;
    }

:victory::victory:

2.1.4f已经解决了