对Cocos2dX的内存管理不了解的人会有这样的疑惑,Cocos2dX的自动内存池是干什么的?当调用一个对象的autorelease后,该对象就被加入到自动内存池中。那是否意味着我们可以不用再去对该对象进行retain,release了呢?
答案是错的。自动内存池只作用于那些”创建期“的对象,也就是说对于那些用create函数创建出来的对象,实际上是调用了autorelease,而autorelease会把该对象加入到自动内存池中,而在用create函数创建了对象后的那一帧,当前自动内存池中的所有对象都会被release一次,然后清空该自动内存池。下面是分析过程:
一.create函数的内幕使用create函数创建对象实际上会调用autorelease,而autorelease又会将该对象加入到当前自动内存池中:
#define CREATE_FUNC(__TYPE__) \static __TYPE__* create() \{ \ __TYPE__ *pRet = new(std::nothrow) __TYPE__(); \ if (pRet && pRet->init()) \ { \ pRet->autorelease(); \ return pRet; \ } \ else \ { \ delete pRet; \ pRet = NulL; \ return NulL; \ } \}
Ref* Ref::autorelease(){ PoolManager::getInstance()->getCurrentPool()->addobject(this); return this;}
二.为什么会有自动内存池 我们来看下每帧中自动内存池会执行什么:
int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdline,int nCmdshow){ UNREFERENCED_ParaMETER(hPrevInstance); UNREFERENCED_ParaMETER(lpCmdline); // create the application instance AppDelegate app; return Application::getInstance()->run();}
int Application::run(){ PVRFrameEnableControlWindow(false); // Main message loop: LARGE_INTEGER nLast; LARGE_INTEGER nNow; queryPerformanceCounter(&nLast); initGLContextAttrs(); // Initialize instance and cocos2d. if (!applicationDIDFinishLaunching()) { return 1; } auto director = Director::getInstance(); auto glvIEw = director->getopenGLVIEw(); // Retain glvIEw to avoID glvIEw being released in the while loop glvIEw->retain(); while(!glvIEw->windowshouldClose()) { queryPerformanceCounter(&nNow); if (nNow.QuadPart - nLast.QuadPart > _animationInterval.QuadPart) { nLast.QuadPart = nNow.QuadPart - (nNow.QuadPart % _animationInterval.QuadPart); director->mainLoop(); glvIEw->pollEvents(); } else { Sleep(1); } } // Director should still do a cleanup if the window was closed manually. if (glvIEw->isOpenglready()) { director->end(); director->mainLoop(); director = nullptr; } glvIEw->release(); return 0;}
run函数中有这么一句,director->mainLoop(),跟踪进去:
voID displaylinkDirector::mainLoop(){ if (_purgeDirectorInNextLoop) { _purgeDirectorInNextLoop = false; purgeDirector(); } else if (_restartDirectorInNextLoop) { _restartDirectorInNextLoop = false; restartDirector(); } else if (! _invalID) { drawScene(); // release the objects PoolManager::getInstance()->getCurrentPool()->clear(); }}
voID autoreleasePool::clear(){#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0) _isClearing = true;#endif std::vector<Ref*> releasings; releasings.swap(_managedobjectArray); for (const auto &obj : releasings) { obj->release(); }#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0) _isClearing = false;#endif}
调用releasings.swap(_managedobjectArray)后当前自动内存池中就被清空了。
for (const auto &obj : releasings) { obj->release(); }创建一个对象时,该对象的引用计数被初始化为1,如果我们没有对该对象进行retain *** 作,或者没有使用它(也就是没有其它对象引用它),那么该对象的引用计数则为1,调用上面的代码后,该对象的引用计数变为0,之后便不复存在。
结论: 自动内存池只作用于创建期的对象,也就是刚用create函数创建的对象。如果我们没有使用它,或者没有进行retain *** 作,那它下一帧就会被清除。 总结
以上是内存溢出为你收集整理的Cocos2dx之为什么会有自动内存池全部内容,希望文章能够帮你解决Cocos2dx之为什么会有自动内存池所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)