Reference count
Reference counting is an ancient way of managing memory in a C + + project. When I was researching an open-source project called TCPMP 8 years ago, the reference count was already there.
The IOS SDK encapsulates this count in NSAutoreleasePool. So we also cloned a set of Ccautoreleasepool in the cocos2d-x. The use of the two is basically the same, so if you haven't been involved in iOS development, you can look at Apple's official document NSAutoreleasePool Class Reference.
Ccautoreleasepool
Cocos2d-x's Ccautoreleasepool and Cocoa's nsautoreleasepool have the same concepts and APIs, but there are two important differences:
Ccautoreleasepool cannot be created by the developer themselves. Cocos2d-x will create an auto-release pool instance object for each of our games, and the game developer can't build a new auto-release pool, just focus on Release/retain cocos2d::ccobject objects.
- Ccautoreleasepool cannot be used in multi-threading, so if your game requires a network thread, simply receive the data in the network thread, change the status flag, and do not call the Cocos2d interface inside the thread. Here's why:
The logic of Ccautoreleasepool is that when you call Object->autorelease (), the object is placed in the auto-free pool. The auto-free pool can help you keep the object's life cycle until the end of the current message loop. At the end of this message loop, if the object is not retain by another class or container, it will be freed automatically. For example, Layer->addchild (Sprite), this sprite is added to the list of child nodes of this layer, and his declaration period continues until the layer is released, not at the end of the current message loop.
This is why you cannot manage the Ccobject lifecycle in the network layer, because automatically releasing objects will be deleted at the end of each UI thread, so when you invoke these deleted objects, you will encounter crash.
In short, there are only two cases where you need to call the release () method
You new a Cocos2d::ccobject object, such as Ccsprite,cclayer.
- You get a pointer to the Cocos2d::ccobject subclass object and then call the Retain method in your code.
The following example does not require calling the retain and release methods:
There is no more code for the sprite. Note, however, that Sripte->autorelease () has been called in the Ccsprite::create (const char*) method, so the sprite will be automatically freed at the end of the message loop.
Using static constructors
Ccsprite::create ("Player.png") is an example of using a static constructor. So all the classes in Cocos2d-x, in addition to the Singleton, provide static constructors that contain the following 4 operations:
Create a new object
Call Object->init (...)
If the initialization succeeds, for example, if the texture file is successfully found, then Object->autorelease () will be called Next.
- Returns the object that has been marked autorelease.
All Ccasdf::createwithxxxx (...) This type of function has all of these methods.
In Cocos2d-x v1.x or earlier, these methods are:
With these static constructors, you don't need to care about "new", "delete" and "autorelease", just the Object->retain () and Object->release ().
An example of a mistake
A developer reports an example of using Ccarray and causing crash
BOOL Helloworld::init () {bool BRet = false; do {////////////////////////////////////////////////////////////////////////////Super Init First CC_BREAK_IF (! Cclayer::init ()); Add your codes below ...////// ccsprite* BOMB1 = ccsprite::create ("Closenorm Al.png "); ccsprite* BOMB2 = ccsprite::create ("Closenormal.png"); ccsprite* bomb3 = ccsprite::create ("Closenormal.png"); ccsprite* bomb4 = ccsprite::create ("Closenormal.png"); ccsprite* bomb5 = ccsprite::create ("Closenormal.png"); ccsprite* Bomb6 = ccsprite::create ("Closenormal.png"); AddChild (bomb1,1); AddChild (bomb2,1); AddChild (bomb3,1); AddChild (bomb4,1); AddChild (bomb5,1); AddchILD (bomb6,1); m_pbombsdisplayed = Ccarray::create (bomb1,bomb2,bomb3,bomb4,bomb5,bomb6,null); M_pbombsdisplayed is defined as a protected variable in the header file. <---We should add the M_pbombsdisplayed->retain () method here to prevent crash in Helloworld::refreshdata (). This->scheduleupdate (); BRet = true; } while (0); return bRet;} void Helloworld::update (Cctime dt) {refreshdata ();} void Helloworld::refreshdata () {m_pbombsdisplayed->objectatindex (0)->setposition (CPP (100,100));}
His mistake is that m_pbombsdisplayed is using ccarray::create (...) Created, this method of creation is statically constructed, and the array is tagged with autorelease.
So this array will be ccautoreleasepool released at the end of the current message loop.
When the subsequent message loop calls Helloworld::update (Cctime), m_pbombsdisplayed is already a wild pointer, which will cause a crash.
In order to fix this crash situation, we need to increase m_pbombsdisplayed->retain () in m_pbombsdisplayed =ccarray::create (...); M_pbombsdisplayed->release () is then called in the destructor of Helloworld::~helloworld ().
(cocos2d-x) reference count (Reference count) and auto-free pool (autoreleasepool) in the