Bug with CCSprite

Hi!

I have a situation where some strange bug appears…

I have a sprite where I do setPosition. But when setPosition is called another function is called and the program crashes.

It works like this:

@
bool Init()
{

m_pSprite = CCSprite::create(…);


}

void SomeFunc(const CCPoint& pos)
{
m_pSprite~~>setPosition;

this~~>addChild(m_pSprite, 2);
}
@

If I put “this~~>addChild” function to Init function all will be OK.
Strange.
I tried to rebuild solution several times but the same~~shit- happens.

When are you calling this SomeFunc? m_pSprite = CCSprite::create(…); creates an autoreleased object which is automatically deleated so if you use it somewhere later not in init funtion it might not exist anymore. this->addChild retains object so it wont be release automatically and I believe that is your problem. You can read about memory management here: http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Reference_Count_and_AutoReleasePool_in_Cocos2d-x

Leszek Leszek wrote:

When are you calling this SomeFunc? m_pSprite = CCSprite::create(…); creates an autoreleased object which is automatically deleated so if you use it somewhere later not in init funtion it might not exist anymore.

Not true if m_pSprite is a member variable. I’ve been doing this many times and all works fine.

As for the code, is it needed for addChild* to be in a separate method than thecreate()* method? In my opinion, creating an object and not adding it (if it needs to be added) on the layer on a separate method is bad practice.

Lance Gray wrote:

Not true if m_pSprite is a member variable. I’ve been doing this many times and all works fine.

It does not matter if m_pSprite is a member variable or a local variable. Cocos2d-x object created with CCSprite::create(…) will always be deleted after one program loop if you do not retain it before this loop ends. Of course everything works fine if you use addChild() because it retains the object automatically.

Leszek thank you! This is it.

Pavel Totolin wrote:

Leszek thank you! This is it.
Can you tell me what the solution was, please?

P. E. wrote:

Pavel Totolin wrote:
> Leszek thank you! This is it.
Can you tell me what the solution was, please?

The solution is to do retain() to a sprite. And when you don’t need it you do release(), otherwise your object will be deleted automatically

And when you need to call previously created nodes, always use tags instead of pointers.

Adamos . wrote:

And when you need to call previously created nodes, always use tags instead of pointers.

Can you please explain why to always use tags instead pointers. What is the benefit? Looking the source of getChildByTag it has to iterate over all the children (worst case) to get the object/pointer. If we have a pointer we get the object in constant time. Well that’s my opinion and I don’t see a benefit in using tags always, maybe cleaner code, but not sure if it does good to performance. If there is something I’m not aware please point it out.

Thanks

Example.

  CCControlButton *button = StandardButton::create(title, size);
  button->addTargetWithActionForControlEvents(
    this,
    cccontrol_selector(StandardDialogSender::dialogCallback), //this class callback
    CCControlEventTouchUpInside
  );
  this->_button = button;
  CCLog("_button: %p, button: %p", this->_button, button);
  layer->addChild(button);
/*...*/
void StandardDialogSender::dialogCallback(CCObject *sender, CCControlEvent controlEvent)
{
  CCLog("_button: %p, sender: %p", this->_button, sender);
  if(_button == sender) {

first log shows two equal pointers.
in second log _button value is 0x0 (as set in class constructor).
Using of tags avoid such problems…

Adamos . wrote:

Example.
[…]
first log shows two equal pointers.
in second log _button value is 0x0 (as set in class constructor).
Using of tags avoid such problems…

Well … I have code where I use pointers from the class in the callback, tested on Linux, Android and BlackBerry, and in my case the pointers are the same, I don’t get the same problem.

P.S.

I have tested the sender and class pointer from a CCMenuItemImage and they are also same

It’s because your class was inherited from CCObject.
Mine is not.
So, callback function calls not for the same object but for new one %)

Adamos . wrote:

It’s because your class was inherited from CCObject.
Mine is not.
So, callback function calls not for the same object but for new one %)

Oh, I see. I’ll keep that in mind.

Thanks

Thank you - I lost whole this day until found that and this discussion helps me :slight_smile: