Cocos2dx之为什么会有自动内存池

Cocos2dx之为什么会有自动内存池,第1张

概述         对Cocos2dX的内存管理不了解的人会有这样的疑惑,Cocos2dX的自动内存池是干什么的?当调用一个对象的autorelease后,该对象就被加入到自动内存池中。那是否意味着我们可以不用再去对该对象进行retain,release了呢? 答案是错的。自动内存池只作用于那些”创建期“的对象,也就是说对于那些用create函数创建出来的对象,实际上是调用了autorelease,

对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之为什么会有自动内存池所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1072624.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存