How correctly release CCSprite memory after CCMoveTo

Hi,
I create a code to simple show and hide a sprite in my screen, this is the code:

CCSprite* pSprite = CCSprite::spriteWithFile(“SpaceFlier_sm_1.png”);
CCSize size = CCDirector::sharedDirector()>getWinSize;
pSprite
>setPosition( ccp(size.width / 2, - pSprite~~>getContentSize.height / 2) );
this~~>addChild(pSprite, 10);

CCFiniteTimeAction *seq = CCSequence::actions(
CCMoveTo::actionWithDuration(1.0f, CCPoint(size.width / 2,pSprite~~>getContentSize.height / 2)),
CCDelayTime::actionWithDuration,
CCMoveTo::actionWithDuration.height / 2)),
NULL);
pSprite~~>runAction(seq);
//this~~>removeChild;
But I want to know how I can release the memory, if I uncomment the following line
this~~>removeChild(pSprite, false);

The sprite don’t appear in the screen.
How I can retain it and release it after the CCMoveTo?

I’ve got the same problem and my solution is the custom CCRemove action. Here’s the source:

class CCRemove : public CCActionInstant
{
public:
    static CCRemove* action();

    virtual void startWithTarget(CCNode* pTarget);
    virtual CCObject* copyWithZone(CCZone* pZone);
};

CCRemove* CCRemove::action()
{
    CCRemove* pRet = new CCRemove();

    pRet->autorelease();

    return pRet;
}

void CCRemove::startWithTarget(CCNode* pTarget)
{
    CCActionInstant::startWithTarget(pTarget);
    m_pTarget->removeFromParentAndCleanup(true);
}

CCObject* CCRemove::copyWithZone(CCZone* pZone)
{
    CCZone* pNewZone = NULL;
    CCRemove* pRet = NULL;

    if (pZone != NULL && pZone->m_pCopyObject)
    {
        pRet = (CCRemove*)(pZone->m_pCopyObject);
    }
    else
    {
        pRet = new CCRemove();
        pZone = pNewZone = new CCZone(pRet);
    }

    CCActionInstant::copyWithZone(pZone);

    CC_SAFE_DELETE(pNewZone);
    return pRet;
}

You can use CCRemove::action() as the last element in your sequence of actions.

The solution above would work, but I think it could be over kill re-writing all that functionality.
My way of doing this would be to declare a quick remove function like so:

Header:

void RemoveChildSeq(CCObject* pObj);

Main declaration:

void ClassName::RemoveChildSeq(CCObject* pObj)
{
    //there should be more error checking in here to check that it is a child etc.
    this->removeChild(pObj, false);
}

Then it is as simple as calling this as an action in your sequence:

//this may be CCCallFuncO::actionWithTarget depending on your release of cocos2d-x
CCAction* removeChild = CCCallFuncO::create(this, callfuncO_selector(ClassName::RemoveChildSeq), pSprite);

I used the solution described by Phill Jones because I think it’s easy to implement.

I need to make a little adaptation since I use a old version of cocos2d-x(0.12.0).

But I receive the following error from this code

void RemoveChildSeq(CCObject* pObj);

invalid conversion from 'cocos2d::CCObject*' to 'cocos2d::CCNode*'

I change it to:

void RemoveChildSeq(CCNode* pObj);

and work’s for me,

thank you ‘Phill Jones’ and ‘redaur redaur’ for help.

Just a little remark: with

void RemoveChildSeq(CCNode* pObj)

you should use CCCallFuncN and callfuncN_selector, it’s a little more type safe.

1 Like

I use the CCCallFuncN with the callfuncN_selector.
The CCCallFuncN it’s better than CCCallFuncO, because the callfuncO_selector need 3 parameters and the callfuncN_selector need only 2 parameters.

A example:

CCAction* removeChildLabel = CCCallFuncO::actionWithTarget(this, callfuncO_selector(HelloWorld::RemoveChildSeq), pLabel);
CCAction* removeChildSprite = CCCallFuncO::actionWithTarget(this, callfuncO_selector(HelloWorld::RemoveChildSeq), pSprite);

CCAction* removeChild = CCCallFuncN::actionWithTarget(this, callfuncN_selector(HelloWorld::RemoveChildSeq));

I can use a single CCAction to remove any child object instead of create a CCAction for each object that I want to remove.

It doesn’t matter for simple actions, but in general case you can’t reuse actions because each action object stores progress of it’s application. You need to make a copy before applying.

Or this solution, but you can’t use this for removeFromParentAndCleanup(false), only for removeFromParentAndCleanup(true).
callfuncN_selector will pass pointer of mysprite as bool argument.

CCCallFuncN callRemove = CCCallFuncN::create);
CCFiniteTimeAction
seq = CCSequence::create(actionMoveIn, CCDelayTime::create(delay), actionMoveOut, callRemove, NULL);

I used the method described by Petr Votocek and it works!

You can now use CCRemoveSelf action with cocos2d-x 2.1

Thanks everyone for the help. I get my game works perfect now, in future I’ll try to use the CCRemoveSelf action.