Hi,
I would like to ask You how the objects must be relieved/disposed, how can I destroy unused objects in Cocos2d-x?
Hi,
I would like to ask You how the objects must be relieved/disposed, how can I destroy unused objects in Cocos2d-x?
When should I release the objects?
I hope this reply can help you.
Hi,
I found that the implemented auto release pool and related classes can not be used in more than two threads. Are you plan to redesign it for multi-threading environment?
Both cocos2d-iphone & cocos2d-x are not designed for multi-thread usage. You had to add locks by yourself.
Itâs not only locking. If you look at the implementation, all auto release pools are added to the same stack no matter in which thread they are. This means while one thread is adding objects to the release pool on the top of the stack, the main thread may start to release the objects in the pool. This can not be prevented by using locks with user code. cocos2d-iphone does not suffer from this problem because in cocoa, each thread (including the main thread) maintains its own stack of NSAutoreleasePool object.
oops, ur right. Itâs lucky that we havenât wrap pthread interfaces yet.
We would consider about this. issue #354 is created for this.
Thanks much for Your reply. I donât understand all the things You have told about releasing the objects.
You wrote that âFor example, layer~~>addChild, the sprite is add to the children list of layer, its lifecycle is retained till the release of layer". This means that the sprite object wouldnât be released when I would call the layer~~>removeChild(sprite, true) method? I think that the if I would setâbool cleanup" parameter to true, the object would be released, and if I would set it to false, it wouldnât, am I right?
And the other question⌠is that any method in CCLayer class that I should use to release the objects? You know⌠I mean - the âspecialâ method, which would be done at the end of the program - is it right to overload the destroy() method in CCLayer class, or should I avoid doing this? When should I write âsprite->release()â, if it should be done only when the program was ended? (the good example may be the âplayer spriteâ, which the player usually see during during the whole game)
@zz
Well, I highlight this sentence in my previous post. And thereâs no any code using âspriteâ. Ofcourse you can removeChild and release it in your code, but this isnât in the premise above. When refcount == 0, this object will be delete immediately.
For the 2nd question, just call object->release().Just focus on the refCount of objects, itâs not too hard to trace.
@zz:
>> âis that any method in CCLayer class that I should use to release the objects? You know⌠I mean - the âspecialâ method, which would be done at the end of the program - is it right to overload the destroy() method in CCLayer class, or should I avoid doing this?â
Iâve found the destroy() method to be a very bad way to release objects. More often than not, the method isnât even called, even when an object is released through the autorelease pool. I donât know if this behavior is by design or not, but it sure adds a lot of memory leaks if youâre not aware of it. Itâs probably better to ignore destroy() and use the destructor instead.
The system seems to be built with the idea of having everything based on NS/CCObject. If youâre not using CCObject everywhere and youâre mixing it up with custom memory management, things will get iffy. Therefore, initializing at onEnter and deiniting at onExit seems to be the better way if you donât want to be leaking memory at CCLayer.
(to Walzer and his team: feel free to correct me Iâm just basing my opinion on hours and hours of hunting down memory leaks)
The function destroy is designed for multiple inheritance.
CCLayer inherites CCNode, CCTouchDelegate and others. Because not all platform support RTTI, so CCTouchDelegate canât inherite CCObject. If CCTouchDelegate inheirte CCObject, there will be a diamond inheritance like this:
CCObject
/ \
/ \
CCNode CCTouchDelegate
\ /
\ /
CCLayer
When we hold a pointer of CCNode that point CCLayer*
CCNode * pNode = new CCLayer();
Than we can not dereference the pointer to CCTouchDelegate*, because the RTTI is not support.
CCTouchDelegate doesnât inherite CCObject, so it has not methods retain() and release(). How can we keep the refrence correct? So destroy and keep are designed for this purpose. You can see the usage of them in CCTouchHandler::setDelegate().
Random thought: Shall we move m_nTag from CCNode to CCObject, so developers can set tag to each cocos2d-x object, than dump CCAutoreleasePool to see which object isnât released as expect? Will it be helpful?
So if I type CCLabelBMFont::labelWithString ("hello", FONT);
, I still need to call autorelease ()
? Cause in my code, I have a LOT of calls like:
@
CCMenuItemLabel *x = CCMenuItemLabel::itemWithLabel (CCLabelBMFont::labelWithString (âHello!â, FONT), this, menu_selector (Menu::callback));
@
Does this mean I still need to call autorelease on everything?
why do you need to call autorelease()?
the implementation of labelWithString() is as follows:
CCLabelBMFont CCLabelBMFont::labelWithString
{
CCLabelBMFontpRet = new CCLabelBMFont();
if(pRet && pRet~~>initWithString)
{
pRet~~>autorelease();
return pRet;
}
CC_SAFE_DELETE(pRet)
return NULL;
}
you donât need to call autorelease() by yourself.
so when do I need to call autorelease
? cause in Walzerâs post, he says you call it when you use new
, retain
, or use a static method to create the object? Does he mean only the static methods that start with init
like CCSprite
âs initWithSpriteFrameCache
?
Hey,
I suggest we move the userdata pointer from CCNode to CCObject so that we can add some dynamic behavior to all CCObject. What do you think?
how do I use the return value of getUserData?
Before you can get anything with getUserData, you need to call setUserData. What you get back with getUserData is what you passed to setUserDate
If we all agree, I will provide a patch for moving the user data point from CCNode to CCObject.
`Cesar de Padua
The rule is the sample as objc NSAutoreleasePool & cocos2d-iphone. When you get an object from static methods just like CCSprite::initWithSpriteFrameCache, this static method set the object to autorelease, so you need to release it unless you call retain once more.
`Leon Li
Sorry, I donât agree with you. CCObject is only for memory management, and CCNode is the basic node in cocos2d. They have different aims. In other words, thereâs no userData pointer in cocoa NSObject.
If you want to add some dynamic behavior to the classes, why not inherit from CCNode instead?
Walzer: sorry, I'm still confused... does that apply to ALL static methods, or only the ones that start with
init@?