Cocos2Dx 内存管理封装

来源:互联网 发布:oracle数据库备份语句 编辑:程序博客网 时间:2024/05/17 01:35

刚接触Cocos2Dx感觉,架构比较清晰合理,但就是内存管理机制对于本人来说实在是感觉很奇怪。

每次创建对象都是用creatXXX方法,如果要保持对象指针还需要retain,销毁时还要记得release,着实很烦人。

本人尝试了使用类似智能指针的方式存储,感觉还不错。

 

先说一下原先Cocos2Dx自动内存管理机制:

    在Cocos2Dx的CCObject类中有这么两个函数retain、release,和一个变量m_uReference,用于控制引用计数,当调用一次retain 引用计数加一,当调用release时引用计数减一、如果此时引用计数为0则delete,另外还有一个函数autorelease,这个函数会在所有的静态工厂方法中调用(CCXXX::create()),此方法的作用是将对象放入内存管理池(CCPoolManage)而在每一帧结束时清除,引用计数为1(只有内存管理池拥有的)的对象。

    在官方的例子中可以看出不希望开发者手工管理内存(new),但是如果自动管理就必须每时每刻记得retain、release,否则要么是野指针要么就会内存泄露,如果在项目后期才注意此问题,那时可能已经无力回天了。

    所以我写了一个类似智能指针的模版解决此问题,不废话了,上代码:

 

#ifndef _CCPTR_H_#define _CCPTR_H_NS_CC_BEGINtemplate<class _Ty>class CCPtr{public:typedef CCPtr<_Ty> _Myt;explicit CCPtr(_Ty *_Ptr = 0): _Myptr(_Ptr){CC_SAFE_RETAIN(_Myptr);}explicit CCPtr(_Myt const & _Ref): _Myptr(_Ref.get()){CC_SAFE_RETAIN(_Myptr);}_Myt& operator=(_Myt& _Right){_Ty* ptr = _Right.get();CC_SAFE_RETAIN(ptr);CC_SAFE_RELEASE(_Myptr);_Myptr = ptr;return (*this);}_Myt& operator=(_Ty* ptr){CC_SAFE_RETAIN(ptr);CC_SAFE_RELEASE(_Myptr);_Myptr = ptr;return (*this);}template<class _Other>operator CCPtr<_Other>(){return (CCPtr<_Other>(*this));}template<class _Other>_Myt& operator=(CCPtr<_Other>& _Right){_Other* ptr = _Right.get();CC_SAFE_RETAIN(ptr);CC_SAFE_RELEASE(_Myptr);_Myptr = ptr;return (*this);}template<class _Other>CCPtr(CCPtr<_Other>& _Right): _Myptr(_Right.get()){CC_SAFE_RETAIN(_Myptr);}~CCPtr() {CC_SAFE_RELEASE(_Myptr);}_Ty& operator*() const{return (*get());}_Ty *operator->() const {return (get());}_Ty *get() const {return (_Myptr);}private:_Ty *_Myptr;// the wrapped object pointer};template<class T, class U> inline bool operator==(CCPtr<T> & a, CCPtr<U> & b) { return a.get() == b.get(); } template<class T, class U> inline bool operator!=(CCPtr<T> & a, CCPtr<U> & b) { return a.get() != b.get(); } typedef CCPtr<CCAction> CCActionPtr;typedef CCPtr<CCActionInterval> CCActionIntervalPtr;typedef CCPtr<CCActionCamera> CCActionCameraPtr;typedef CCPtr<CCActionManager> CCActionManagerPtr;typedef CCPtr<CCActionEase>  CCActionEasePtr;typedef CCPtr<CCPageTurn3D>  CCActionPageTurn3DPtr;typedef CCPtr<CCGridAction>  CCActionGridPtr;typedef CCPtr<CCProgressTimer>  CCActionProgressTimerPtr;typedef CCPtr<CCGrid3D>  CCActionGrid3DPtr;typedef CCPtr<CCActionInstant>  CCActionInstantPtr;typedef CCPtr<CCActionTween>  CCActionTweenPtr;typedef CCPtr<CCAffineTransform>  CCAffineTransformPtr;typedef CCPtr<CCDictionary>  CCDictionaryPtr;typedef CCPtr<CCObject>  CCObjectPtr;typedef CCPtr<CCArray>  CCArrayPtr;typedef CCPtr<CCSet>  CCSetPtr;typedef CCPtr<CCAutoreleasePool>  CCAutoreleasePoolPtr;typedef CCPtr<CCInteger>  CCIntegerPtr;typedef CCPtr<CCFloat>  CCFloatPtr;typedef CCPtr<CCDouble>  CCDoublePtr;typedef CCPtr<CCBool>  CCBoolPtr;typedef CCPtr<CCString>  CCStringPtr;typedef CCPtr<CCZone>  CCZonePtr;typedef CCPtr<CCAnimation> CCAnimationPtr;typedef CCPtr<CCNode> CCNodePtr;// add other typedef// ...NS_CC_END#endif // _CCPTR_H_

由于涉及类太多,没有把所有的类的模版全都加好,各位用到什么自己加一下吧。

用法以CCNode为例。

我们在类的头文件里定义一个CCNodePtr的成员m_testNode

然后在用到它的地方对它赋值就可以了。^_^

m_testNode = CCNode::create();

然后可以进行你需要的操作

例如:m_testNode->setPositionX(0);

用法和操作CCNode*一样,

你不需要关心retain、release了,但是需要注意一点在传参时不能传递的CCPtr的引用和指针只能传递对象,用法类似boost中智能指针用法^_^

 

欢迎转载,转载时请注明出处,谢谢!

原创粉丝点击