The source code version comes from 3.x. For more information, see
Cocos2d-x source code analysis directory:
Http://blog.csdn.net/u011225840/article/details/31743129
1. Ref, AutoreleasePool, and PoolManagerRef contain a reference count called referenceCount. When a Ref class variable is new, the reference count of its referenceCount is set to 1. There are three important operations: retain, release, and autorelease. The following is a detailed description of the source code analysis. AutoreleasePool is stored in the ref that is displayed to call autorealse, and its clear function is called after each frame. The displayed call is stored in the realse function of the ref, and itself is cleared. PoolManager manages the AutoreleasePool of shards. There is no error. There is not only one AutoreleasePool, but also multiple autoreleasepools.
2. source code analysis if you want to clearly understand the cocos2d-x 3.x memory management mechanism, please be patient to read the code here, the source code itself is clear and easy to understand, what's more, I have added some necessary Chinese comments ~
2.1 Ref source code analysis of important member variables: _ referenceCount, which is set to 1 in the constructor. Remember.
void Ref::retain(){ CCASSERT(_referenceCount > 0, "reference count should greater than 0"); ++_referenceCount;}
Ref* Ref::autorelease(){ PoolManager::getInstance()->getCurrentPool()->addObject(this); return this;}
void Ref::release(){ CCASSERT(_referenceCount > 0, "reference count should greater than 0"); --_referenceCount; if (_referenceCount == 0) { delete this; }}
Some of the macros and functions used to Debug or track memory leak have been removed. In fact, the nature of these three functions is so simple. retain and release increase and decrease referenceCount respectively, the release function deletes itself when count is 0. The autorelease function puts the Ref into the current AutorealsePool. Attention Please: each of the three functions has a CCASSERT. The referenceCout of this object must be greater than 0 during the call. Release or autorealse must be paired with new or retain.
Here we will talk about the basic usage, because the classes we need to manage and use generally inherit from Node (Layer, Sprite, etc.). Let's look at the create function of Node. In create of Node, after new (Count is set to 1) is called, autoRelease is called immediately and put into AutoreleasePool. (The source code of AutoreleasePool will be analyzed later) So after you use create, do not use release or Autorelease unless you have manually retain once. However, when you add node1 to another node2, you can understand that the refereneceCount of node1 is added once, but you do not need to perform any additional operations. Because when node1 is removed or no remove operation is performed, when node2 is parsed (the count of its child is reduced by 1 ). That is to say, the entire engine automatically manages referenceCount, as long as you do not need to manually retain.
2.2 AutoreleasePool source code analysis
void AutoreleasePool::clear(){#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0) _isClearing = true;#endif for (const auto &obj : _managedObjectArray) { obj->release(); } _managedObjectArray.clear();#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0) _isClearing = false;#endif}
The clear function of AutoRealse is very clear, that is, to call the release function of its contained ref, and then clear its own managedObject. The question to be resolved here is when the clear function is called. Open Director's source code
void DisplayLinkDirector::mainLoop(){ if (_purgeDirectorInNextLoop) { _purgeDirectorInNextLoop = false; purgeDirector(); } else if (! _invalid) { drawScene(); // release the objects PoolManager::getInstance()->getCurrentPool()->clear(); }}
When your App is running, each frame is first drawScene () at the beginning. After the display on various interfaces is complete, it starts to clear.
2.3 PoolManager std: deque <AutoreleasePool *> _ releasePoolStack;
AutoreleasePool * _ curReleasePool; PoolManager manages all autorerealsepools and has a pointer pointing to the current releasePool. It is worth noting that I think 3. x has a small bug.
PoolManager* PoolManager::getInstance(){ if (s_singleInstance == nullptr) { s_singleInstance = new PoolManager(); // Add the first auto release pool s_singleInstance->_curReleasePool = new AutoreleasePool("cocos2d autorelease pool"); s_singleInstance->_releasePoolStack.push_back(s_singleInstance->_curReleasePool); } return s_singleInstance;}
PoolManager is a singleton mode. When it is initialized for the first time, an AutoreleasePool is automatically generated and placed in its own stack. However, when you open the AutoreleasePool constructor, you find that one of them has called PoolManager: getInstance ()-> push (this); tracing Through debug, I found that there are two autorealsepools. That is, the poolManager stack has two locations pointing to the same AutoRealsePool. It seems that this is a Bug.
3. Summary 1.Ref, AutorealsePool, and PoolManager are closely related. 2. retain and new of Ref should be paired with release or autoRealse. 3. How to Use Node.