自己动手写cocos2dx游戏引擎(七)——自动释放池

前端之家收集整理的这篇文章主要介绍了自己动手写cocos2dx游戏引擎(七)——自动释放池前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

上一节说到的Ref的引用计数时,没有说自动释放。

自动释放功能相对来说比较复杂。

首先有一个自动释放池。

#ifndef __AUTORELEASEPOOL_H__
#define __AUTORELEASEPOOL_H__

#include <string>
#include <vector>
#include "Ref.h"

class AutoreleasePool {
    public:
        AutoreleasePool();
        AutoreleasePool(const std::string &name);
        ~AutoreleasePool();
        void addObject(Ref *object);
        void clear();
        bool contains(Ref* object) const;
    private:
        std::vector<Ref*> _managedObjectArray;// 对象数组,存放自动释放的对象
        std::string _name;// 释放池名字
};

class PoolManager {
    public:
        static PoolManager* getInstance();
        static void destroyInstance();

        AutoreleasePool *getCurrentPool() const;
        bool isObjectInPools(Ref* obj) const;

        friend class AutoreleasePool; 
    private:
        PoolManager();
        ~PoolManager();
    
        void push(AutoreleasePool *pool);
        void pop();

        static PoolManager* s_singleInstance;
        std::vector<AutoreleasePool*> _releasePoolStack;
};

AutoreleasePool::AutoreleasePool(): _name("") {
    _managedObjectArray.reserve(150);
   PoolManager::getInstance()->push(this);
}

AutoreleasePool::AutoreleasePool(const std::string &name): _name(name) {
    _managedObjectArray.reserve(150);
   PoolManager::getInstance()->push(this);
}

AutoreleasePool::~AutoreleasePool() {
    clear();
    PoolManager::getInstance()->pop();
}

void AutoreleasePool::clear() {
    // 与一个默认大小的vector交换,使其恢复到默认大小
    // 再释放临时的vector对象,已达到释放内存,恢复到默认大小的目的
    std::vector<Ref*> releasings;
    releasings.swap(_managedObjectArray);
    std::vector<Ref*>::iterator it = releasings.begin();
    for (; it != releasings.end(); it++) {
        (*it)->release();
    }
}

bool AutoreleasePool::contains(Ref* object) const {
    std::vector<Ref*>::const_iterator it = _managedObjectArray.begin();
    for (; it != _managedObjectArray.end(); it++) {
        if(object == (*it)) {
            return true;
        }
    }
    return false;
}

void AutoreleasePool::addObject(Ref* object) {
    _managedObjectArray.push_back(object);
}

/*
 * PoolManager
 * */
PoolManager* PoolManager::s_singleInstance = NULL;

PoolManager* PoolManager::getInstance() {
    if (NULL == s_singleInstance) {
        s_singleInstance = new PoolManager();
        // 创建单例的后悔初始化自动释放池
        new AutoreleasePool("cocos2d autorelease pool");
    }
    return s_singleInstance;
}

void PoolManager::destroyInstance() {
    delete s_singleInstance;
    s_singleInstance = NULL;
}

PoolManager::PoolManager() {
    _releasePoolStack.reserve(10);
}

PoolManager::~PoolManager() {
    while (!_releasePoolStack.empty()) {
        AutoreleasePool* pool = _releasePoolStack.back();
        delete pool;
    }
}

AutoreleasePool* PoolManager::getCurrentPool() const {
    return _releasePoolStack.back();
}

bool PoolManager::isObjectInPools(Ref* obj) const {
    std::vector<AutoreleasePool*>::const_iterator it =  _releasePoolStack.begin();
    for (;it != _releasePoolStack.end(); ++it) {
       if ((*it)->contains(obj)) {
            return true; 
       } 
    }
    return false;
}

void PoolManager::push(AutoreleasePool *pool) {
    _releasePoolStack.push_back(pool);
}

void PoolManager::pop() {
    if (!_releasePoolStack.empty()) {
        _releasePoolStack.pop_back();
    }
}

#endif

当我们调用Ref对象的autorelease方法时,就会当该对象加入到自动释放池中。

Ref* Ref::autorelease()
{
    PoolManager::getInstance()->getCurrentPool()->addObject(this);
    return this;
}

另外,还有一个自动释放池对象PoolManager,专门来管理自动释放池。

自动释放管理对象是一个单例,但我们第一次获取这个单例的时候,就会创建一个自动释放池。

PoolManager* PoolManager::getInstance() {
    if (NULL == s_singleInstance) {
        s_singleInstance = new PoolManager();
        // 创建单例的后初始化自动释放池
        new AutoreleasePool("cocos2d autorelease pool");
    }   
    return s_singleInstance;
}

然后在Director的mainLoop中,每一帧都会检测自动释放池,release对象,释放引用计数为0的对象。

void DisplayLinkDirector::mainLoop() {
    drawScene();
    // 每一帧都会检测自动释放池
    PoolManager::getInstance()->getCurrentPool()->clear();
}

代码 原文链接:https://www.f2er.com/cocos2dx/340562.html

猜你在找的Cocos2d-x相关文章