CCARRAYを慎むFOREACH


初めて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マクロの定義:
#define CCARRAY_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__++)

私の元のコードでCCARRAYを展開するとFOREACHマクロの場合、コードは次のようになります.
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が呼び出される
関数、
最終的にcc ArrayRemoveObjectAtIndexのmemmove((void*)&arr->arr[index],(void*)&arr->arr[index+1],remaining*sizeof(CCObject*);
memmove関数では、CCArrayで現在削除されている項目を削除し、その後の項目を前に移動するので、2つの連続する項目Tagが1の精霊がA、Bであり、現在の_arr__A精霊を指し、現在の__をarr__指し示すエルフ(Aエルフ)を削除した後、同時に実行して後ろのBエルフを前に移動したので、本輪サイクル終了後、実行_arr__++後、_arr__B精霊の後ろの精霊の住所を指しているので、B精霊は網を漏らす魚になった.
結論:CCARRAYではないFOREACHがCCArrayを巡回している間に、中にあるオブジェクトを削除します.でもCCARRAY_FOREACH_REVERSEマクロ、このマクロは後ろから遍歴しているからです.