When to retain objects in Cocos2dx

I want to know about when to retain an object please consider two scenarios .
void create()
{
*animSetAbatchNode=CCSpriteBatchNode::create; // creating a batchNode,*animSetAbatchNode is field of some class and create is function in that class. Do I need to retain it in order to use it in other function of same class ?
firstFrameSetA=CCSprite::createWithSpriteFrameName; // like wise , do i need to retainfirstFrameSetA also ? if I am using it in another function of same class ?
}

void scrollDown()
{
_animSetAbatchNode~~>setPosition; // x some variable.
_firstFrameSetA~~>setPosition(ccp(*blockWidth*1.1f,*blockWidth*1.55f));
}

what confuses me is the batchNode and sprite I created above both are autoReleased inside there create functions. By autoRelease I understand as soon as they are returned to my pointers , there retain count will be reduced by 1. But when I check the retain count in above code it shows 1 . Now I am not getting how this 1 came ? I didn’t retain it and the function which created it , has already autoReleased it. So whether I should retain above pointers or not ? Pleases share your views ?
Also Its is said that if retain count is zero then those objects will be de allocated at the end of the message loop. But what is “message loop” ? .

There are simple rules with retain() and autorelease():

  1. everything I create with new are mine and I’m responsible for deleting them from memory
  2. everything returned using a create()-method is autoreleased and will be released when the CURRENT METHOD ENDS. If the retainCount is zero, they will be purged from memory. When I need them in an instance variable I have to retain them.
  3. everything I retain I’ll have to release to purge this from memory.

See this retain/release thing as a reference counter. If the counter is down to zero the object will be deleted.

2 Likes

thanks for the clarification Jesko…
One more thing , If I retain an object in a function . Where to release it ? in same function after it has been used ? e.g.

1> I create a CCSprite then I retain it and add it to the batchNode
2> Then I create sequence of actions and I retain it.
3> then I use this sequence to runAction on CCSprite created in first step.

Now where to release the retained objects ? in the same function ? after running animation or in the callback function which will be called once the animation is done. I cannot wait for destructor as it will be called only when the game is quitted. So where to release
Please share your thoughts .

In this scenario you do not have to retain this objects. Adding a node as achild automatically retains it. It is also true for a CCAction - when it is used as an argument to runAction, it will also be retained automatically.

In my experience, retain - release should be used when you need to keep a reference for an object for future use, and don’t want to add this object as a child to something (scene, layer, etc.)

1 Like

Please consider this case:

I am running same animation on different sprites, here it is how I am achieving it :-

for(short i=0;i<maxRows;++i)
{
for(short j=0;j<maxCols;++j)
{
if(shapePtr->getTopChildInfo(i,j)!=0)
{
CCSpriteBatchNode *animStarBatchNode=CCSpriteBatchNode::create(“animStar.png”,100);// no need to retain.
this~~>addChild;
CCSprite *s=CCSprite::createWithSpriteFrameName;// no need to retain
animStarBatchNode~~>addChild(s,5);
s~~>setPosition*_blockWidth,_blockWidth));
CCSequence
seq = CCSequence::createWithTwoActions,CCCallFuncO::create,animStarBatchNode));
s~~>runAction(seq);
}
}
}

where “animation” used in sequence is created from CCAnimation and is declared outside above for loop, so as the loop goes on retain Count for animation increases depending on if condition there .
1> Do I need to worry about this count as I am not explicitly retaining it ?
2> or Should I refactor my code for avoiding such conditions ? where retain count keeps on increasing ?
3> In the call back function showSparklesFinished I am removing all children from the bacthNode animStarBatchNode and then removing animStarBatchNode from its parent (a layer )and as I am creating new batchNode every loop and sending them to the call back function so is it sure that every batchNode will be removed from its parent in the call back function one by one I am seeing possibility of memory leak.

Please share your thoughts

EDIT:
Similarly the retain count of “seq” object increases as its inside the for loop and added every time runAction is called.

In your example everything you create will be automatically destroyed when the animStarBatchNode will removed from parent. You only have to call retain() if you want to own something. And only then you have to call release() to remove your ownership. This retain/release thing was introduced to cocos2dx for easy handling memory.
But consider - only for performance reasons - not to create and destroy batchnodes and sprites in every runloop. Allocating and deleting something from memory is time consuming. Best practice would be to allocate a pool of sprites in the init() method of the scene and using them throughout the game.

its an old thread, but may help someone, the “message loop” usually referred here most likely is the one delta call, so its not the end of the method or scope when they mention end of message loop, else all the create method will stop working as intended (because auto release is called inside create and then the object is returned without adding to the parent), and that is also the reason, why you can keep passing the object back to caller function and caller function then adds it to parent. I think in the document it should be cleared, its a wonderful engine but every time you need to know more you have to digg into the code to understand.

I had some trouble with storing a Sprite returned by create() in a Player object. These Players were stored in a vector and the Sprite were not added to a layer/scene/node/. When I tried to use them the reference was invalid because they were deleted from memory. Using retain keeps them in memory. Should I manually release these in the Player dtor?