A chain reaction, that is, if an object is released, it will also release the object it references.The above is a general process of an object. We divide the object into two periods. One is the initial period and the Self-reference is 1. (if it is 0, the object will be released. This is the basic principle, so it must be greater than 0), and the other is the use period. As mentioned above, in order to ensure that objects in the creation period are not destroyed, self-reference (not actually used) is initialized to 1, which means we need a proper time,.
When? When the frame is too large! (This ensures that the current frame can correctly use the object without being destroyed .) How to release? Because it is a self-reference, we cannot access it in other ways, so we have an automatic release pool, And we convert "self-reference" to "Auto Release pool reference" in disguise ", to mark an object in the creation period ".
ThenWhen the frame is too large, the "Release pool reference" is released by automatically releasing the pool management, which means that the "own reference" is removed ". Objects after excessive frames are managed by users.
Conclusion: by understanding the above paragraph, we can understand:
When an object is just created (create, new + autorelease), the pool is automatically released to retain reference to the object ("reference itself"), so that the reference count is 1.
During Frame Transition, the CCPoolManager: sharedPoolManager ()-> pop () in the main loop of the game. If a method is called once, the "self-reference" is automatically removed ", in fact, all objects in the automatically released pool are release once. Therefore, the object can have at least one frame. (Of course, if the reference count of an object is 0, the object will be released .)
void CCPoolManager::pop(){ if (! m_pCurReleasePool) { return; } int nCount = m_pReleasePoolStack->count(); m_pCurReleasePool->clear(); if(nCount > 1) { m_pReleasePoolStack->removeObjectAtIndex(nCount-1);// if(nCount > 1)// {// m_pCurReleasePool = m_pReleasePoolStack->objectAtIndex(nCount - 2);// return;// } m_pCurReleasePool = (CCAutoreleasePool*)m_pReleasePoolStack->objectAtIndex(nCount - 2); } /*m_pCurReleasePool = NULL;*/}
In this method, we can know that the release process is as follows:
In the previous article Cocos2d-x Memory Management Mechanism (1) we already know that the CCPoolManager object automatic release management class stores a current object automatic release pool and an object release pool array.
In the pop method, the clear operation is performed on the automatic release pool of the current object, which is obviously to unreference all objects in the current release pool. Enter the clear method as follows:
void CCAutoreleasePool::clear(){ if(m_pManagedObjectArray->count() > 0) { //CCAutoreleasePool* pReleasePool;#ifdef _DEBUG int nIndex = m_pManagedObjectArray->count() - 1;#endif CCObject* pObj = NULL; CCARRAY_FOREACH_REVERSE(m_pManagedObjectArray, pObj) { if(!pObj) break; --(pObj->m_uAutoReleaseCount); //(*it)->release(); //delete (*it);#ifdef _DEBUG nIndex--;#endif } m_pManagedObjectArray->removeAllObjects(); }}
We can see in the for loop -- (pObj-> m_uAutoReleaseCount); this is to remove the Automatic Object Management for the referenced object, and the automatic management value is reduced by one.
When an object is added to the Auto Release pool, m_uAutoReleaseCount = 1 indicates automatic management for the Auto Release pool. Then, after 1 is subtracted, m_uAutoReleaseCount = 0 indicates that the auto release pool is not managed.
We can also note that CCARRAY_FOREACH_REVERSE uses reverse order to release the reference. We can also guess that the automatic release pool uses a stack structure (FILO ).
-- M_uAutoReleaseCount. That is, m_pManagedObjectArray-> removeAllObjects (); all objects in the pool will be automatically released for removal, so we will find that the removal process is actually a release operation on the object, because the m_uReference value after the object autorelease is 1, the release becomes 0, and the object is automatically released.
So after this clear, all objects in the object pool in the current automatic management are removed from the reference.
Then let's go back to the pop method,
if(nCount > 1) { m_pReleasePoolStack->removeObjectAtIndex(nCount-1);// if(nCount > 1)// {// m_pCurReleasePool = m_pReleasePoolStack->objectAtIndex(nCount - 2);// return;// } m_pCurReleasePool = (CCAutoreleasePool*)m_pReleasePoolStack->objectAtIndex(nCount - 2); }
After the current object is automatically released to the clear pool, you need to delete the object from the automatically released pool array; then, use the second Auto Release pool in the array as the current Auto Release pool.
From here, we can also roughly understand that the automatic release of the pool array is essentially a stack structure, but it is implemented through arrays.
The process of automatically releasing the pool to unreference is roughly like this!
Iv. Summary
These two articles roughly describe the memory management in cocos2dx. In fact, there are two aspects in summary:
① Add objects to the Auto Release pool for Automatic Management (creation period );
② The automatic release pool removes the automatic management of objects and is handed over to the objects using this object for Management (use period ).
There should be no problems in understanding the process!