91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

坑爹的CCARRAY_FOREACH

發布時間:2020-06-14 23:16:22 來源:網絡 閱讀:770 作者:584851044 欄目:編程語言

第一次使用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函數,

最終定位到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宏,因為這個宏是從后面遍歷的。


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

青川县| 五指山市| 灵石县| 太白县| 黑河市| 徐闻县| 平昌县| 象州县| 汝州市| 德安县| 朔州市| 鹤壁市| 苍梧县| 新晃| 高淳县| 老河口市| 仪陇县| 临湘市| 宜川县| 荔浦县| 丰都县| 桂林市| 永德县| 安化县| 沂水县| 东源县| 松滋市| 老河口市| 阳新县| 晋州市| 张掖市| 孝感市| 昌邑市| 道真| 新宾| 嘉祥县| 靖宇县| 丁青县| 图们市| 西贡区| 平泉县|