cocos2dx 之内存管理

cocos2dx 采用引用计数管理自己的内存:

引用计数:

             引用计数就是通过给每个对象维护一个引用计数器,记录该对象当前被引用的次数。当对象增加一次引用时,计数器+1.而对象失去一次引用时,计数器-1,当引用计数器为0时。标志着该对象的生命周期结束,自动触发对象的回收释放。
             为了实现引用计数器,cocos2dx实现了自己的根类ccobject。引 擎中所有类都派生自ccobject类。一下ccobject的定义
class CC_DLL Object
{
public:
    /// object id, ScriptSupport need public _ID
    unsigned int        _ID;
    /// Lua reference id
    int                 _luaID;
protected:
    /// count of references
    unsigned int        _reference;
    /// count of autorelease
    unsigned int        _autoReleaseCount;
public:
    /**
     * Constructor
     *
     * The object's reference count is 1 after construction.
     * @js NA
     */
    Object();
    
    /**
     * @js NA
     * @lua NA
     */
    virtual ~Object();
    
    /**
     * Release the ownership immediately.
     *
     * This decrements the object's reference count.
     *
     * If the reference count reaches 0 after the descrement, this object is
     * destructed.
     *
     * @see retain, autorelease
     * @js NA
     */
    inline void release()
    {
        CCASSERT(_reference > 0, "reference count should greater than 0");
        --_reference;

        if (_reference == 0)
            delete this;
    }

    /**
     * Retains the ownership.
     *
     * This increases the object's reference count.
     *
     * @see release, autorelease
     * @js NA
     */
    inline void retain()
    {
        CCASSERT(_reference > 0, "reference count should greater than 0");
        ++_reference;
    }

    /**
     * Release the ownership sometime soon automatically.
     *
     * This descrements the object's reference count at the end of current
     * autorelease pool block.
     *
     * If the reference count reaches 0 after the descrement, this object is
     * destructed.
     *
     * @returns The object itself.
     *
     * @see AutoreleasePool, retain, release
     * @js NA
     * @lua NA
     */
    Object* autorelease();

    /**
     * Returns a boolean value that indicates whether there is only one
     * reference to the object. That is, whether the reference count is 1.
     *
     * @returns Whether the object's reference count is 1.
     * @js NA
     */
    bool isSingleReference() const;

    /**
     * Returns the object's current reference count.
     *
     * @returns The object's reference count.
     * @js NA
     */
    unsigned int retainCount() const;

    /**
     * Returns a boolean value that indicates whether this object and a given
     * object are equal.
     *
     * @param object    The object to be compared to this object.
     *
     * @returns True if this object and @p object are equal, otherwise false.
     * @js NA
     * @lua NA
     */
    virtual bool isEqual(const Object* object);
    /**
     * @js NA
     * @lua NA
     */
    virtual void acceptVisitor(DataVisitor &visitor);
    /**
     * @js NA
     * @lua NA
     */
    virtual void update(float dt) {CC_UNUSED_PARAM(dt);};
    
    friend class AutoreleasePool;
};
通过以上代码我们可以看出cocos2dx的内存管理机制和objective-c的管理一样。都是当 _reference = 0时释放内存。 _autoReleaseCount自动释放池的引用计数
		auto sprite1 = new Sprite();
		sprite1->initWithSpriteFrameName("btn_adventure_normal_CN.png");//引用计数器+1
		CCLOG("retaincount = %d",sprite1->retainCount());
		sprite1->retain();//引用计数器+1
		CCLOG("retaincount = %d",sprite1->retainCount());
		sprite1->release();//引用计数器-1
		CCLOG("retaincount = %d",sprite1->retainCount());
		sprite1->autorelease();//只是把该sprite放入自动释放池中。引用计数器不变。等待管理器自动释放
		CCLOG("retaincount = %d",sprite1->retainCount());

coco2dx 内存管理原则

1.程序段必须成对执行retain()和release()或者执行autorelease()来开始和结束对对象的引用
2.工厂方法返回前,应通过autorelease()结束对该对象的引用
3.对象传值时,应考虑到新旧对象相同的特殊情况
4.尽量使用release()而不是autorelease()来释放对象,以确保性能。
5.保存ccobject的子类对象时,应严格使用cocos2dx提供的容器。

内存管理涉及到的宏:

#define CC_SYNTHESIZE_RETAIN(varType, varName, funName)    \
private: varType varName; \
public: virtual varType get##funName(void) const { return varName; } \
public: virtual void set##funName(varType var)   \
{ \
    if (varName != var) \
    { \
        CC_SAFE_RETAIN(var); \
        CC_SAFE_RELEASE(varName); \
        varName = var; \
    } \
} 

#define CC_SAFE_DELETE(p)           do { delete (p); (p) = nullptr; } while(0)
#define CC_SAFE_DELETE_ARRAY(p)     do { if(p) { delete[] (p); (p) = nullptr; } } while(0)
#define CC_SAFE_FREE(p)             do { if(p) { free(p); (p) = nullptr; } } while(0)
#define CC_SAFE_RELEASE(p)          do { if(p) { (p)->release(); } } while(0)
#define CC_SAFE_RELEASE_NULL(p)     do { if(p) { (p)->release(); (p) = nullptr; } } while(0)
#define CC_SAFE_RETAIN(p)           do { if(p) { (p)->retain(); } } while(0)



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值