前幾天移植了Obj-c的CCScrollLayer,當然也發現cocos2d-x引擎的作者也對其進行過移植,我將自己移植的CCScrollLayer類在自己的新游戲中使用,但是卻發現有bug,並且是這個類帶來不斷的debug也找不出問題...最后與王哲移植的進行比較,發現他的代碼中有一個這樣的代碼
1 // Can't use createWithArray because layer does not implemnt CCCopying 2 // m_pLayers = CCArray::createWithArray(layers); 3 m_pLayers = CCArray::create(); 4 m_pLayers->addObjectsFromArray(layers);
而我是直接使用
m_pLayers = CCArray::createWithArray(layers);
於是進入CCArray的createWithArray方法,發現代碼如下
CCArray* CCArray::createWithArray(CCArray* otherArray) { CCArray* pRet = (CCArray*)otherArray->copy(); pRet->autorelease(); return pRet; }
CCObject* CCObject::copy() { return copyWithZone(0); }
CCObject* CCCopying::copyWithZone(CCZone *pZone) { CC_UNUSED_PARAM(pZone); CCAssert(0, "not implement"); return 0; }
#define CC_UNUSED_PARAM(unusedparam) (void)unusedparam
然后我就頓悟了,使用一個根類CCCopying就能實現copy?想多了吧。子類的所有數據都不知道,CCCopy其實只是實現一個讓copy()接口用於調用copyWithZone(),平時我們使用CCMove等Action的時候,能夠進行Copy是因為CCMove對copyWithZone進行重新,C++的多態性,CCMove的實例調用copy時會調用子類的copyWithZone,所有實現CCMove等動作類的copy。
但是CCArray並沒有實現CCCopying,所以...慎用copy()!請注意永遠不要使用createWithArray()!至於王哲為何留着createWithArray()這個坑來坑人...也許是人蛋疼,當我想是商業原因吧。
2013/5/10修改: 再看一下CCArray的源碼,發現CCArray有實現copyWithZone,但是有一個問題,就是copy的時候每個CCObject都需要進行copy,所以要確保CCArray的所有CCObject都自行實現了copyWithZone。但是,如果其他有一個或多個未實現的話,問題就來了...