1.1.02_COCOS2D-X内存管理之HelloWorld

2017-07-04  本文已影响33人  资深小夏
bool AppDelegate::applicationDidFinishLaunching()
{
    ...
    // create a scene. it's an autorelease object
    auto scene = HelloWorld::scene();

    // run
    director->runWithScene(scene);

    return true;
}
Scene* HelloWorld::scene()
{
     return HelloWorld::create();
}
Scene* Scene::create()
{
    Scene *ret = new (std::nothrow) Scene();
    if (ret && ret->init())
    {
        ret->autorelease();
        return ret;
    }
    else
    {
       ...
    }
}
Ref::Ref()
: _referenceCount(1) // when the Ref is created, the reference count of it is 1
...
Ref* Ref::autorelease()
{
    PoolManager::getInstance()->getCurrentPool()->addObject(this);
    return this;
}

此时,HelloWorld场景对象已经被加入了内存自动回收池,并且引用计数为1


void Director::runWithScene(Scene *scene)
{
    ...
    pushScene(scene);
    ...
}
void Director::pushScene(Scene *scene)
{
    ...
    _scenesStack.pushBack(scene);
    ...
}
/** Adds a new element at the end of the Vector. */
void pushBack(T object)
{
    CCASSERT(object != nullptr, "The object should not be nullptr");
    _data.push_back( object );
    object->retain();
}
void Ref::retain()
{
    CCASSERT(_referenceCount > 0, "reference count should be greater than 0");
    ++_referenceCount;
}

void Director::mainLoop()
{
    ...
    else if (! _invalid)
    {
        drawScene();
        // release the objects
        PoolManager::getInstance()->getCurrentPool()->clear();
    }
}
void AutoreleasePool::clear()
{
    ...
    std::vector<Ref*> releasings;
    releasings.swap(_managedObjectArray);
    for (const auto &obj : releasings)
    {
        obj->release();
    }
    ...
}
void Ref::release()
{
    CCASSERT(_referenceCount > 0, "reference count should be greater than 0");
    --_referenceCount;
    if (_referenceCount == 0)
    {
        ...
        delete this;
    }
}

至此,在下一帧结束前,HelloWorld的场景对象引用计数变成了1。同时由于_managedObjectArray被清空,所以在下下帧时,执行clear就不会再对HelloWorld场景对象做release()处理。也就是说其引用计数保持为1。


void Director::replaceScene(Scene *scene)
{
    ...
    _scenesStack.replace(index, scene);
    ...
}
void replace(ssize_t index, T object)
{
    CCASSERT(index >= 0 && index < size(), "Invalid index!");
    CCASSERT(object != nullptr, "The object should not be nullptr");
    
    _data[index]->release();
    _data[index] = object;
    object->retain();
}

替换当前索引的场景对象,并将原持有对象释放。

上一篇 下一篇

猜你喜欢

热点阅读