1 class CC_DLL CCCopying 2 { 3 public: 4 virtual CCObject* copyWithZone(CCZone* pZone); 5 };
class CC_DLL CCZone { public: CCZone(CCObject *pObject = NULL); public: CCObject *m_pCopyObject; };
CCCopying 类是最简单的一个类了。
只有一个构造函数,用CCZone初始化一个CCobject
只是相当于一个接口的作用。
再看看CCZone类的定义
只有一个CCObject* m_pCopyObject;
主要用来保存CCObject对象的。
可以看看CCZone的构造函数
1 CCZone::CCZone(CCObject *pObject) 2 { 3 m_pCopyObject = pObject; 4 }
可以看到,只是保存了CCObject的对象,CCZone中人是为了CCObject子类之间拷贝作用的。
比如CCAction::copyWithZone(CCZone *pZone) 的实现,代码如下:
CCObject* CCAction::copyWithZone(CCZone *pZone) { CCZone *pNewZone = NULL; CCAction *pRet = NULL; if (pZone && pZone->m_pCopyObject) { pRet = (CCAction*)(pZone->m_pCopyObject);//这一句,可以看到,CCZone只是方便拷贝使用的。 } else { pRet = new CCAction(); pNewZone = new CCZone(pRet); } //copy member data pRet->m_nTag = m_nTag; CC_SAFE_DELETE(pNewZone); return pRet; }
CCObject继承自CCopying,CCObject有两个功能。提供了引用计数,主要用来进行内存管理的。又分为手动内存管理和自动内存管理。
看下CCObject类的定义
1 class CC_DLL CCObject : public CCCopying 2 { 3 public: 4 5 //这两个是支持lua等脚本语言用的,可以先不用管 6 unsigned int m_uID; . 7 int m_nLuaID; 8 protected: 9 unsigned int m_uReference; //对象的引用计数的 10 unsigned int m_uAutoReleaseCount;//自动内存管理的 11 public: 12 CCObject(void); 13 virtual ~CCObject(void); 14 void release(void); // 自减1 , m_uReference == 0时,delete this,销毁自己 15 void retain(void); // 自增1 , m_uReference++ ; 16 CCObject* autorelease(void); // 自动内存管理的。CCPoolManager::sharedPoolManager()->addObject(this);CCPoolManager是个内存池管理的 17 CCObject* copy(void); // CCObject的拷贝机制,内存就一句代码 return copyWithZone(0); ,可见,是调用了copyWithZone 18 bool isSingleReference(void) const; // 判断是不是单个引用 19 unsigned int retainCount(void) const; // 返回引用数 20 virtual bool isEqual(const CCObject* pObject); //判断两个对象是否是同一个对象 21 22 virtual void acceptVisitor(CCDataVisitor &visitor); 23 virtual void update(float dt) {CC_UNUSED_PARAM(dt);}; 24 friend class CCAutoreleasePool; // 把CCAutoreleasePool设为CCObject的友元类,是为了方便CCAutoreleasePool访问CCObject中的成员进而进行内存管理 25 };
相应的CCObject实现代码如下,可以参照上面的注释进行理解
1 CCObject* CCCopying::copyWithZone(CCZone *pZone) 2 { 3 CC_UNUSED_PARAM(pZone); 4 CCAssert(0, "not implement"); 5 return 0; 6 } 7 8 CCObject::CCObject(void) 9 : m_nLuaID(0) 10 , m_uReference(1) // when the object is created, the reference count of it is 1 11 , m_uAutoReleaseCount(0) 12 { 13 static unsigned int uObjectCount = 0; 14 15 m_uID = ++uObjectCount; 16 } 17 18 CCObject::~CCObject(void) 19 { 20 // if the object is managed, we should remove it 21 // from pool manager 22 if (m_uAutoReleaseCount > 0) 23 { 24 CCPoolManager::sharedPoolManager()->removeObject(this); 25 } 26 27 // if the object is referenced by Lua engine, remove it 28 if (m_nLuaID) 29 { 30 CCScriptEngineManager::sharedManager()->getScriptEngine()->removeScriptObjectByCCObject(this); 31 } 32 else 33 { 34 CCScriptEngineProtocol* pEngine = CCScriptEngineManager::sharedManager()->getScriptEngine(); 35 if (pEngine != NULL && pEngine->getScriptType() == kScriptTypeJavascript) 36 { 37 pEngine->removeScriptObjectByCCObject(this); 38 } 39 } 40 } 41 42 CCObject* CCObject::copy() 43 { 44 return copyWithZone(0); 45 } 46 47 void CCObject::release(void) 48 { 49 CCAssert(m_uReference > 0, "reference count should greater than 0"); 50 --m_uReference; 51 52 if (m_uReference == 0) 53 { 54 delete this; 55 } 56 } 57 58 void CCObject::retain(void) 59 { 60 CCAssert(m_uReference > 0, "reference count should greater than 0"); 61 62 ++m_uReference; 63 } 64 65 CCObject* CCObject::autorelease(void) 66 { 67 CCPoolManager::sharedPoolManager()->addObject(this); 68 return this; 69 } 70 71 bool CCObject::isSingleReference(void) const 72 { 73 return m_uReference == 1; 74 } 75 76 unsigned int CCObject::retainCount(void) const 77 { 78 return m_uReference; 79 } 80 81 bool CCObject::isEqual(const CCObject *pObject) 82 { 83 return this == pObject; 84 } 85 86 void CCObject::acceptVisitor(CCDataVisitor &visitor) 87 { 88 visitor.visitObject(this); 89 }
另外介绍3个宏,分别是NS_CC_BEGIN ,NS_CC_END ,USING_NS_CC
定义分别如下
#define NS_CC_BEGIN namespace cocos2d {
#define NS_CC_END }
#define USING_NS_CC using namespace cocos2d
通过定义可以得知,前面两个宏的其实就是用来进行命名空间的声明的。
namespace cocos2d{
// here your code
}
第3个宏,是在使用 using namespace cocos2d 时可以用USING_NS_CC 代替,个人觉得完全没有必要,直接写觉得更好。
今天就写到这,写的不完善,还请见谅