浅谈CCArray:慎用copy
前几天移植了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。但是,如果其他有一个或多个未实现的话,问题就来了...