[SOLVED] Bug? CCMenu->removeAllChildrenWithCleanup(true) raised an exception on CCMenuItem::activate()

I got an exception on line

 CCScriptEngineManager::sharedManager()->getScriptEngine()->executeMenuItemEvent(this);

in

void CCMenuItem::activate()

I called:
CCMenu->removeAllChildrenWithCleanup(true)

This works (Called on the same method):

CCMenuItemFont* label = CCMenuItemFont::create("blabla", this, menu_selector(HelloWorld::menuCallback) );
test->setPosition(ccp(150,150));
contextMenu = CCMenu::create(label, NULL);
this->addChild(contextMenu, 1);

contextMenu->removeAllChildrenWithCleanup(true);

Calling contextMenu->removeAllChildrenWithCleanup(true) on HelloWorld::menuCallback() crashed on d CCMenuItem::activate();

Is it a bug or my mistake?

Here is the function which calls the CCMenuItem::activate()

void CCMenu::ccTouchEnded(CCTouch *touch, CCEvent* event)
{
    CC_UNUSED_PARAM(touch);
    CC_UNUSED_PARAM(event);
    CCAssert(m_eState == kCCMenuStateTrackingTouch, "[Menu ccTouchEnded] -- invalid state");
    if (m_pSelectedItem)
    {
        m_pSelectedItem->unselected();
        m_pSelectedItem->activate();
    }
    m_eState = kCCMenuStateWaiting;
}

Hope it helps to detect the reason for the exception.

Try removing the label from the parent.

 label->stopAllActions();
 label->removeFromParentWithCleanup(true). 

or at least menu->stopAllActions() first

going that direction seems safer

Sorry it is not helping me:

Here are the callstack:

    libcocos2d.dll!cocos2d::CCMenuItem::activate() Line 119 C++
    libcocos2d.dll!cocos2d::CCMenuItemLabel::activate() Line 233    C++
    libcocos2d.dll!cocos2d::CCMenu::ccTouchEnded(cocos2d::CCTouch * touch, cocos2d::CCEvent * event) Line 260   C++
    libcocos2d.dll!cocos2d::CCTouchDispatcher::touches(cocos2d::CCSet * pTouches, cocos2d::CCEvent * pEvent, unsigned int uIndex) Line 377  C++
    libcocos2d.dll!cocos2d::CCTouchDispatcher::touchesEnded(cocos2d::CCSet * touches, cocos2d::CCEvent * pEvent) Line 509   C++
    libcocos2d.dll!cocos2d::CCEGLViewProtocol::handleTouchesEnd(int num, int * ids, float * xs, float * ys) Line 307    C++

It crashing allways on this methode:

void CCMenuItem::activate()
{
    if (m_bEnabled)
    {
        if (m_pListener && m_pfnSelector)
        {
            (m_pListener->*m_pfnSelector)(this);
        }

        if (kScriptTypeNone != m_eScriptType)
        {
            CCScriptEngineManager::sharedManager()->getScriptEngine()->executeMenuItemEvent(this);  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< CRASHING here!!!!!!
        }
    }
}

Maybe an important hint:
Menu will be created on overwritten method:

void HelloWorld::ccTouchesEnded(CCSet* touches, CCEvent* event)

Using an own layer for this menu and it is working very well.

Using an own layer for this menu and it is working very well.

In CCMenuItem::activate() your target->selector will be called. If you remove the menu item within this method, your CCMenuItem will be released and destroyed while it’s activated method is still running. A fix for that problem is to retain and release the CCMenuItem in its activate() method. This way it will be destroyed earliest when activated() has been finished.

void CCMenuItem::activate() {
    retain();
    if (m_bEnabled)
    {
        if (m_pListener && m_pfnSelector)
        {
            (m_pListener->*m_pfnSelector)(this);
        }
        if (kScriptTypeNone != m_eScriptType)
        {
            CCScriptEngineManager::sharedManager()->getScriptEngine()->executeMenuItemEvent(this);
        }
    }
    release();
}
1 Like

wow, this helped me to solve a lot of random crashes on android and some on ios, thank you Christian