坑爹的CCARRAY_FOREACH

坑爹的CCARRAY_FOREACH,第1张

概述第一次使用CCARRAY_FOREACH遍历一个CCArray数组并且删除数组里的东西时发生出乎意料的结果: 类似代码如下: CCArray *children = this->getChildren();CCObject *temp = NULL;CCARRAY_FOREACH(children, temp){    CCSprite *sprite = dynamic_cast<CCSp

第一次使用CCARRAY_FOREACH遍历一个CCArray数组并且删除数组里的东西时发生出乎意料的结果:
类似代码如下:

CCArray*children=this->getChildren();CCObject*temp=NulL;CCARRAY_FOREACH(children,temp){CCSprite*sprite=dynamic_cast<CCSprite*>(temp);if(sprite->getTag()==1){this->removeChild(sprite);}}



这段代码执行下来,发现有些Tag为1的精灵没有被删除,为了查原因,我追查到CCARRAY_FOREACH宏的定义中:

#defineCCARRAY_FOREACH(__array__,__object__)\if((__array__)&&(__array__)->data->num>0)\for(CCObject**__arr__=(__array__)->data->arr,**__end__=(__array__)->data->arr+(__array__)->data->num-1;\__arr__<=__end__&&(((__object__)=*__arr__)!=NulL/*||true*/);\__arr__++)


如果在我原来的代码中展开宏的话,代码为如下形式:
if((children&&children->data->num>0)for(CCObject**__arr__=children->data->arr,**__end__=children->data->arr+children->data->num-a;__arr__<=__end__&&(((temp)=*__arr__)!=NulL);__arr__++){CCSprite*sprite=dynamic_cast<CCSprite*>(temp);if(sprite->getTag()==1){this->removeChild(sprite);}}


然后追踪到voID CCNode::removeChild(CCNode* child)->

voID CCNode::removeChild(CCNode* child,bool cleanup)->

voID CCNode::detachChild(CCNode *child,bool doCleanup)->

最后定位到detachChild中的m_pChildren->removeObject(child);是关键

m_pChildren是一个CCNode中的一个CCArray类型变量,CCArray中调用removeObjectsInArray又调用了ccArray类中的ccArrayRemoveArray函数,

最终定位到ccArrayRemoveObjectAtIndex中的memmove((voID *)&arr->arr[index],(voID *)&arr->arr[index+1],remaining * sizeof(CCObject*));


memmove函数中把CCArray中当前要删的那个项删掉,然后后面的项往前移动,所以当有两个连续的项Tag为1的精灵为A、B,并且当前的__arr__指向A精灵,当把当前__arr__指向的精灵(A精灵)删掉后,同时也执行了把后面B精灵往前移动了,所以本轮循环结束后,执行__arr__++后,__arr__指向的是B精灵后面的精灵的地址,所以B精灵成为了漏网之鱼。

结论:不要在CCARRAY_FOREACH遍历CCArray时删除里面存的对象。但是可以用CCARRAY_FOREACH_REVERSE宏,因为这个宏是从后面遍历的。

总结

以上是内存溢出为你收集整理的坑爹的CCARRAY_FOREACH全部内容,希望文章能够帮你解决坑爹的CCARRAY_FOREACH所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1079201.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)