cocos2d-x的内存管理和CCObject类

本文探讨了cocos2d-x的内存管理机制,源自于cocos2d并通过引用计数控制。重点分析了基类CCObject以及CCAutoreleasePool的角色。通过实例展示了对象创建、autorelease和release的过程,说明了内存回收池的工作原理,强调了'谁管理,谁负责释放'的原则。
摘要由CSDN通过智能技术生成

在这里要先明白cocos2d-x内存管理的来源。因为cocos2d-x是将cocos2d重写了一遍,内存管理也是和cocos2d一样,通过引用计数来控制。其实现是在cocos2d-x的基类CCObject中,所以要弄懂cocos2d-x的内存管理,一定会跟CCObject类打交道。所以可以从CCObject类下手。

class CC_DLL CCObject : public CCCopying
{
public:
    // object id, CCScriptSupport need public m_uID
	//与脚本相关,略过
    unsigned int        m_uID;
    // Lua reference id
    //与脚本相关,略过
    int                 m_nLuaID;
protected:
    // count of references
    //引用计数
    unsigned int        m_uReference;
    // count of autorelease
    //在内存回收池的引用次数,也就是调用一次autorelease这个值加1
    unsigned int        m_uAutoReleaseCount;
public:
    //构造
    CCObject(void);
    /**
     *  @lua NA
     */
    //析构
    virtual ~CCObject(void);
    //引用计数减一,为0回收内存
    void release(void);
    //引用计数加1
    void retain(void);
    //把当前对象加入到内存回收池中
    CCObject* autorelease(void);
    //拷贝
    CCObject* copy(void);
    //是否单引用
    bool isSingleReference(void) const;
    //返回当前的引用计数
    unsigned int retainCount(void) const;
    //是否是同一个对象
    virtual bool isEqual(const CCObject* pObject);
    //实现观察者观察CCObject对象
    virtual void acceptVisitor(CCDataVisitor &visitor);
    //更新
    virtual void update(float dt) {CC_UNUSED_PARAM(dt);};
    //声明CCAutoreleasePool为友元类
    friend class CCAutoreleasePool;
};
再看其实现:

CCObject::CCObject(void)
: m_nLuaID(0)
, m_uReference(1) // 当对象被创建时,应用计数初始化为1,这样便能保证该对象至少能存活一帧
, m_uAutoReleaseCount(0)
{
    static unsigned int uObjectCount = 0;

    m_uID = ++uObjectCount;//与脚本相关,略过
}

CCObject::~CCObject(void)
{
    // if the object is managed, we should remove it
    // from pool manager
    if (m_uAutoReleaseCount > 0)//如果当该对象被销毁时,仍存在于内存回收池中,那么内存回收池清掉该对象
    {
        CCPoolManager::sharedPoolManager()->removeObject(this);
    }
    
    // if the object is referenced by Lua engine, remove it
    //下面与脚本引擎相关,略过
    if (m_nLuaID)
    {
        CCScriptEngineManager::sharedManager()->getScriptEngine()->removeScriptObjectByCCObject(this);
    }
    else
    {
        CCScriptEngineProtocol* pEngine = CCScriptEngineManager::sharedManager()->getScriptEngine();
        if (pEngine != NULL && pEngine->getScriptType() == kScriptTypeJavascript)
        {
            pEngine->removeScriptObjectByCCObject(this);
        }
    }
}

CCObject* CCObject::copy()
{
	//拷贝,空实现
    return copyWithZone(0);
}

void CCObject::release(void)
{
    CCAssert(m_uReference > 0, "reference count should greater than 0");
    //引用计数减1
    --m_uReference;

    if (m_uReference == 0)//如果引用计数为0,则删除该对象
    {
        delete this;
    }
}

void CCObject::retain(void)
{
    CCAssert(m_uReference > 0, "reference count should greater than 0");
    //引用计数加1
    ++m_uReference;
}

CCObject* CCObject::autorelease(void)
{
	//加入到自动回收池中
    CCPoolManager::sharedPoolManager()->addObject(this);
    return this;
}

bool CCObject::isSingleReference(void) const
{
	//若果引用计数为1,则表明当前对象是单引用
    return m_uReference == 1;
}

unsigned int CCObject::retainCount(void) const
{
	//返回引用计数
    return m_uReference;
}

bool CCObject::isEqual(const CCObject *pObject)
{
	//判断是否是同一个对象
    return this == pObject;
}

void CCObject::acceptVisitor(CCDataVisitor &visitor)
{
	//调用观察者的visitObject观察该对象
    visitor.visitObject(thi
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值