Possible to check if CCSprite has been released?

I have a pool of objects in the scene that I have to pick up one or two of them to add a glow sprite. It will blink for a few times and then calling a dismiss function to release it. This action is triggered by a button that if there is a new round coming up the previous round should be cancelled. I have created a stack to collect all the glow sprites created, once a new round is coming then I will release everything in the sprite prior to the end of the animation. It is fine if there is actually an action, but if the action is released “naturally”, it will cause a problem because the content inside the stack become 0xfeeefeee (or equivalent).

Is there any way that I can check if the sprite has been released, or my workflow is not proper.

would you show me the code of blink and dismiss? because i can’t know how you did, i can’t find where is the error or other problem.

Thanks for the reply.

Finally, I have checked out a post about dangling pointer


which gives me a clear idea that I am going to a wrong direction, and surprisingly the problem is solved after that.

It is really a great experience that the API is very friendly that you don’t have to worry too much about memory management.
But for my case here, since I have to handle it case by case, so I should disable “autorelease” by “retain”,
otherwise it will become dangling pointer since I stacked up the pointer location.

Code to remove the sprite:

void GameScene::removeGlowEffect(CCNode node)
{
if )
node~~>removeFromParent;
>
CC_SAFE_RELEASE_NULL;
}
Code to create the sprite:
CCSprite *GameScene::addGlowEffect(CCSprite* sprite, const ccColor3B& colour, const float scaleFactor, const GLubyte opacity)
{
if
return NULL;
>
CCPoint pos = ccp.width / 2, sprite~~>getContentSize.height / 2);
>
CCRenderTexture
rt = CCRenderTexture::create(*size.width,*size.height);
rt~~>beginWithClear;
rt~~>visit();
rt~~>end;
>
CCTexture2D *tex = rt~~>getSprite()>getTexture;
>
CCSprite* glowSprite = new CCSprite;
**glowSprite
>retain;*
glowSprite~~>initWithTexture;
glowSprite~~>setColor;
glowSprite~~>setOpacity;
glowSprite~~>setPosition;
glowSprite~~>setRotation);
>
_ccBlendFunc f = ;
glowSprite~~>setBlendFunc;
>
sprite~~>addChild;
>
CCScaleBy**ccSB = CCScaleBy::create;
>
// Run some animation which scales a bit the glow
CCSequence* s1 = CCSequence::createWithTwoActions);
CCRepeat* r = CCRepeat::create;
>
CCSequence *seq = CCSequence::createWithTwoActions));
glowSprite~~>runAction(seq);
>
return glowSprite;
}

The BOLD line is the code added to resolve the issue.
Now the remaining issue is that to solve the memory leak by chance over the retain, it is not successfully cleared even I call the removeGlowEffect in destructor

I am just a few months in cocos2d. really appreciate the community here.

Another issue here.

CC_SAFE_RELEASE_NULL(node);

if I replace this with CC_SAFE_DELETE(node), the memory leak is not here.

I would like to know the reason behind this, or the memory leak checking is incorrect.

I am using CRT library in VS2012 to pick up the memory leak
http://msdn.microsoft.com/en-us/library/x98tx3cf.aspx

I think it’s not good idea to create a CCSprite and retain it in a function, and delete it in another function.
why don’t you try this: new a class extends CCSprite, it owner the feature of blink, and can open and close this feature.

ps: i did’t try the CRT.

Jonathan Yeung wrote:

Another issue here.
>
CC_SAFE_RELEASE_NULL(node);
>
if I replace this with CC_SAFE_DELETE(node), the memory leak is not here.
>
I would like to know the reason behind this, or the memory leak checking is incorrect.
>
I am using CRT library in VS2012 to pick up the memory leak
http://msdn.microsoft.com/en-us/library/x98tx3cf.aspx

I think I may not catch up what you want to say.

What I imagine a new class of blink function is that, the open will be create and retain a CCSprite, and close will be delete it.

Since my experience to cocos2d-x is just a short period of time, I am still keeping an old school mindset that keeping the object invisible or hide but delete it will occupy more memory space or not.

shujun qiao wrote:

I think it’s not good idea to create a CCSprite and retain it in a function, and delete it in another function.
why don’t you try this: new a class extends CCSprite, it owner the feature of blink, and can open and close this feature.
>
ps: i did’t try the CRT.
>
Jonathan Yeung wrote:
> Another issue here.
>
> CC_SAFE_RELEASE_NULL(node);
>
> if I replace this with CC_SAFE_DELETE(node), the memory leak is not here.
>
> I would like to know the reason behind this, or the memory leak checking is incorrect.
>
> I am using CRT library in VS2012 to pick up the memory leak
> http://msdn.microsoft.com/en-us/library/x98tx3cf.aspx

i write a GlowSprite:

//GlowSprite.h
#include "cocos2d.h"

USING_NS_CC;

class GlowSprite : public CCSprite {
private:
    CCSprite* _glow;
    CCSize _size;

    CCSequence* _seq;

public:
    CREATE_FUNC(GlowSprite);

    bool init();

    CCSprite* addGlowEffect(const ccColor3B& colour, const float scaleFactor, const GLubyte opacity);

    void removeGlowEffect();

    void playEffect(bool open);
};

//GlowSprite.cpp
#include "GlowSprite.h"

bool GlowSprite::init()
{
    initWithFile("flag.png");

    _glow = addGlowEffect(ccc3(111,222,12), 0.6, 200);

    this->addChild(_glow, -1);

    CCScaleBy *ccSB = CCScaleBy::create(0.5f, 0.6, 0.6);
    // Run some animation which scales a bit the glow
    CCSequence* s1 = CCSequence::createWithTwoActions(ccSB, ccSB->reverse());
    CCRepeat* r = CCRepeat::create(s1, 5);

    _seq = CCSequence::createWithTwoActions(r, CCCallFuncN::create(this, callfuncN_selector(GlowSprite::removeGlowEffect)));

    _glow->setVisible(false);
    _glow->retain();
    _seq->retain();

    return true;
}
void GlowSprite::playEffect(bool open)
{
    _glow->setVisible(open);
    if (open) {
        _glow->runAction(_seq);
    }
    else{
        _glow->stopAllActions();
    }
}
CCSprite* GlowSprite::addGlowEffect(const ccColor3B& colour, const float scaleFactor, const GLubyte opacity)
{
    if(this == NULL)
        return NULL;
    _size = this->getContentSize();
    CCPoint pos = ccp(_size.width / 2, _size.height / 2);

    CCRenderTexture *rt = CCRenderTexture::create(_size.width, _size.height);
    rt->beginWithClear(255, 255, 255, 60);
    rt->visit();
    rt->end();

    CCTexture2D *tex = rt->getSprite()->getTexture();
    CCSprite* glowSprite = CCSprite::createWithTexture(tex);
    glowSprite->setColor(colour);
    glowSprite->setOpacity(opacity);
    glowSprite->setPosition(pos);
    glowSprite->setRotation(this->getRotation());

    _ccBlendFunc f = {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA};
    glowSprite->setBlendFunc(f);

    return glowSprite;
}

and in HelloWorldScene.cpp

int lastGlowIdx = -1;
void HelloWorld::displayGlow()
{
    int idx = getRand(FLAG_NUM);
    CCLog("idx: %d", idx);
    if (lastGlowIdx != idx) {
        //if 
        if(lastGlowIdx >= 0)
            glows[lastGlowIdx].playEffect(false);

        lastGlowIdx = idx;
        glows[lastGlowIdx].playEffect(true);
    }
}

in function init of HelloWorldScene.cpp

    CCLabelBMFont* createLb = CCLabelBMFont::create("create", "konqa32.fnt");
    CCMenuItemLabel* createItem = CCMenuItemLabel::create(createLb, this, menu_selector(HelloWorld::displayGlow));
    createItem->setPosition(ccp(350, 20));
    _menu = CCMenu::create(createItem, NULL);
    this->addChild(_menu);
    _menu->setPosition(CCPointZero);

    for (int i=0; isetPosition(getPos());
        this->addChild(gl);

        gl->retain();
        glows[i] = * gl;
    };

i hope these will help you.

Jonathan Yeung wrote:

I think I may not catch up what you want to say.
>

//GlowSprite.cpp
#include "GlowSprite.h" 

GlowSprite::GlowSprite(): _glow(0), _seq(0)
{
}

GlowSprite::~GlowSprite()
{
    CC_SAFE_RELEASE_NULL(_glow);
    CC_SAFE_RELEASE_NULL(_seq);
}

GlowSprite* GlowSprite::create(const char *pszFileName)
{
GlowSprite *pobSprite = new GlowSprite();

if (pobSprite && pobSprite->initWithFile(pszFileName))
{
//pobSprite->autorelease();
return pobSprite;
}

CC_SAFE_DELETE(pobSprite);

return NULL;
}

bool GlowSprite::initWithFile(const char *pszFileName)
{
    if (CCSprite::initWithFile(pszFileName))
    {
        _glow = addGlowEffect(ccc3(111,222,12), 1.2f, 200);

        this->addChild(_glow, -1);

        CCScaleBy *ccSB = CCScaleBy::create(0.5f, 1.2f, 1.2f);

        // Run some animation which scales a bit the glow
        CCSequence* s1 = CCSequence::createWithTwoActions(ccSB, ccSB->reverse());
        _seq = CCRepeatForever::create(s1);
        _seq->retain();

        _glow->setVisible(false);
        _glow->retain();

        return true;
    }

    return false;
}

void GlowSprite::playEffect(bool open)
{
    _glow->setVisible(open);

    if (open) {
        _glow->runAction(_seq);
    }
    else{
        _glow->stopAllActions();
    }
}

CCSprite* GlowSprite::addGlowEffect(const ccColor3B& colour, const float scaleFactor, const GLubyte opacity)
{
    if(this == NULL)
        return NULL;

    CCSize _size = this->getContentSize();

    CCPoint pos = ccp(_size.width / 2, _size.height / 2);

    CCRenderTexture *rt = CCRenderTexture::create(_size.width, _size.height);
    rt->beginWithClear(255, 255, 255, 60);
    rt->visit();
    rt->end();

    @CCTexture2D *tex = rt->getSprite()->getTexture();@
    CCSprite* glowSprite = CCSprite::createWithTexture(tex);
    glowSprite->setColor(colour);
    glowSprite->setOpacity(opacity);
    glowSprite->setPosition(pos);
    glowSprite->setRotation(this->getRotation());

    _ccBlendFunc f = {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA};
    glowSprite->setBlendFunc(f);

    return glowSprite;
}

I modified something in case to make it work on my side.
The code looks cleaner. But my concern will be that if it retains too many objects in the scene?

too many objects in the scene??
oh, you can try CCDrawNode.

Jonathan Yeung wrote:

[…]
>
I modified something in case to make it work on my side.
The code looks cleaner. But my concern will be that if it retains too many objects in the scene?

Thanks, I will take a look into the class