转【玩转cocos2d-x之二十五】数据结构CCArray

前端之家收集整理的这篇文章主要介绍了转【玩转cocos2d-x之二十五】数据结构CCArray前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
















原创作品,转载请标明http://www.jb51.cc/article/p-bsovodom-ep.html


CCArray是从cocos2d中移植过来的,类似于Apple的NSMutableArray,但是比NSMutableArray更为的好用。要注意的是虽然CCArray和CCDictionary可以管理cocos2d-x中绝大多数的类,但是仍然无法替代STL库,STL库更为强有力。


1.API

先看一下CCArray可以帮我们做什么。

1.1.创建

  1. //创建array
  2. staticCCArray*create();
  3. //使用一系列CCObject创建array
  4. staticCCArray*create(CCObject*pObject,…);
  5. //使用一个CCObject创建array
  6. staticCCArray*createWithObject(CCObject*pObject);
  7. //创建array并设置容量
  8. staticCCArray*createWithCapacity(unsignedintcapacity);
  9. //用一个已存在的array创建另一个array
  10. staticCCArray*createWithArray(CCArray*otherArray);

1.2.添加

copy
    //添加一个元素
  1. voidaddObject(CCObject*object);
  2. //添加一个已存在array中所有元素
  3. voidaddObjectsFromArray(CCArray*otherArray);
  4. //在指定位置插入元素
  5. voidinsertObject(CCObject*object,unsignedintindex);

1.3.删除

copy
    //移除最后一个元素
  1. voidremoveLastObject(boolbReleaSEObj=true);
  2. //移除某个元素
  3. voidremoveObject(CCObject*object,boolbReleaSEObj=true);
  4. //移除一个指定位置的元素
  5. voidremoveObjectAtIndex(unsignedintindex,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px"> //移除某个array
  6. voidremoveObjectsInArray(CCArray*otherArray);
  7. //移除所有元素
  8. voidremoveAllObjects();
  9. //快速移除某个元素
  10. voidfastRemoveObject(CCObject*object);
  11. //快速移除某个指定位置的元素
  12. voidfastRemoveObjectAtIndex(unsignedintindex);


1.4.操作元素

copy
    //返回元素个数
  1. unsignedintcount()const;
  2. //返回array容量
  3. unsignedintcapacity()const;
  4. //返回指定CCObject的位置,如果不存在返回UINT_MAX
  5. unsignedintindexOfObject(CCObject*object)const;
  6. //返回指定位置的CCObject
  7. CCObject*objectAtIndex(unsignedintindex);
  8. //返回最后一个元素
  9. CCObject*lastObject();
  10. //返回随机元素
  11. CCObject*randomObject();
  12. //返回某个元素是否存在于array中
  13. boolcontainsObject(CCObject*object)const;
  14. //判断array是否相等
  15. boolisEqualToArray(CCArray*pOtherArray);

1.5.操作array内容

copy
    //交换2个元素
  1. voidexchangeObject(CCObject*object1,CCObject*object2);
  2. //交换2个指定位置元素
  3. voidexchangeObjectAtIndex(unsignedintindex1,unsignedintindex2);
  4. //用一个对象替代指定位置元素
  5. voidreplaceObjectAtIndex(unsignedintuIndex,CCObject*pObject,boolbReleaSEObject=true);
  6. //反转array
  7. voidreverSEObjects();
  8. //收缩array内存以匹配元素个数
  9. voidreduceMemoryFootprint();


2.remove和fastremove

从1.3可以看出删除有两种方式,普通删除快速删除,它们有什么区别呢?


2.1.普通删除

copy
    //普通删除
  1. voidccArrayRemoveObjectAtIndex(ccArray*arr,unsignedintindex,boolbReleaSEObj/*=true*/)
  2. {
  3. CCAssert(arr&&arr->num>0&&index<arr->num,"Invalidindex.Outofbounds");
  4. //删除元素内容,位置仍保留着
  5. if(bReleaSEObj)
  6. CC_SAFE_RELEASE(arr->arr[index]);
  7. }
  8. //长度减1
  9. arr->num--;
  10. //获得要删除的元素后的元素个数
  11. unsignedintremaining=arr->num-index;
  12. if(remaining>0)
  13. //将要删除元素后的所有元素逐个向前移动
  14. memmove((void*)&arr->arr[index],(void*)&arr->arr[index+1],remaining*sizeof(CCObject*));
  15. }
  16. }

2.2.快速删除

copy
    //快速删除
  1. voidccArrayFastRemoveObjectAtIndex(ccArray*arr,unsignedintindex)
  2. //删除元素内容,位置仍保留着
  3. CC_SAFE_RELEASE(arr->arr[index]);
  4. //获取最后一个元素
  5. unsignedintlast=--arr->num;
  6. //把最后一个元素插到删除元素的位置上
  7. arr->arr[index]=arr->arr[last];
  8. }

2.3.总结

如果有array={0,1,2,3,4,5},如果要删除3,使用普通删除得到的结果{0,5},使用快速删除得到的结果是{0,5,4}。可以看出快速删除的效率比普通删除效率高,就差在移动元素的时间复杂度上。


3.内存分配


3.1.容量和个数

CCArray中容量和个数并不是同一个概念。个数<=容量。从添加元素的源码中可以看到在添加之前会先进行空间分配,所以它是一个动态分配内存的过程。如下

copy
    voidccArrayEnsureExtraCapacity(ccArray*arr,unsignedintextra)//确保有额外的空间
  1. {
  2. while(arr->max<arr->num+extra)//判断空间是否足够
  3. ccArrayDoubleCapacity(arr);//增加一倍空间
  4. }
所以,每次CCArray在插入数据时检测到空间不足会增加一倍空间,再进行检测,直到空间满足分配为止。


3.2.判等

判断2个CCArray是否相等使用isEqualToArray(),判断相等的条件是CCArray中的每个元素相等即可,与CCArray的容量无关。

4.效率

比起NSMutableArray,CCArray效率能高出10%左右,原因有三:

(1)它使用的是C接口,所以它不有Objective-C消息开销。

(2)它假定你知道你在做什么,所以它不花时间在安全检查上(如边界溢出,空间需求等)。

(3)在比较上使用了指针而不是isEqual。

除了CCArray,我们还看到了ccCArray,CCArray基本上都是调用了ccCArray的函数,为什么要分为2种?

仔细看一下CCArray是继承于CCObject,所以CCArray是用于处理cocos2d-x对象的,内存管理上也有cocos2d-x的autorelease等诸多特性。而ccCArray可以直接操作标准的C数据结构和类型。


5.CCARRAY_FOREACH和CCARRAY_FOREACH_REVERSE

宏定义,用于正向遍历和反向遍历CCArray元素

copy
    @H_667_1301@#defineCCARRAY_FOREACH(__array__,__object__)\
  1. if((__array__)&&(__array__)->data->num>0)\
  2. for(CCObject**__arr__=(__array__)->data->arr,**__end__=(__array__)->data->arr+(__array__)->data->num-1;\
  3. __arr__<=__end__&&(((__object__)=*__arr__)!=NULL/*||true*/);\
  4. __arr__++)
  5. @H_667_1301@#defineCCARRAY_FOREACH_REVERSE(__array__,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px"> for(CCObject**__arr__=(__array__)->data->arr+(__array__)->data->num-1,**__end__=(__array__)->data->arr;\
  6. __arr__>=__end__&&(((__object__)=*__arr__)!=NULL/*||true*/);\
  7. __arr__--)


6.示例

CCArray的使用示例在http://www.jb51.cc/article/p-wfbmoohn-ep.html此文中有比较典型的应用,这里就不再详述。


7.注意

一般来说,CCArray不会被add到其他类,所以它的引用计数是1,而且被设置为自动释放。所以创建CCArray对象时要记得调用retain,而且在析构的时候也要调用release来释放内存。真心想吐槽。。。


============

http://blog.csdn.net/kenkao/article/details/10375683

一.基本用法

1.声明初始化变量

2.添加元素到数组

3.删除元素

4.遍历

1).使用ccarray中的宏进行遍历

2).for循环遍历

二.注意事项

1.创建一个CCArray后如果不是立刻使用的话一定要调用retain,增加引用计数,不然会被自动释放!

2.删除CCArray中的元素时最好默认内部调用一次release,不然可能会内存泄露!

3.遍历时删除元素

三.什么时候会用到CCArray?

1.每一个CCNode的children本质就是一个CCArray,这样我们就可以通过getChildren()获得array,进行操作!

2.对于CCSequence如果只有到运行时才能知道有个少个动作时,我们就可以声明一个CCArray然后将动作addObject(),最后通过一个array来创建CCSequence,例如下面这段代码:

3.对于一个CCSprite,我们肯定需要把它addChild到parent上,这样他才能显示出来,这样的话parent上就会有好多child,但是我们要遍历只是其中的一部分(例:场景的地图上有好多种花,我们都会把它们添加到同一个parent上,这时候策划说其中的一种花会被怪物踩死?纳尼….,这个时候我们就需要唉将能被踩死的花加入到parent上时同时加入到一个CCArray中去….),这样我们用的时候遍历这个数组就可以了,而不是遍历这个children!

4.多谢@子龙山人 大大的添加,CCArray还可以内存预分配,比如预先生成一堆子弹,然后加到CCArray中,再从这个CCArray中去重用子弹。这样可以提高游戏效率。消失的子弹只需要设置为Invisible就可以了。这个在做射击类游戏中会大量使用的!

5.还有其他用法?发评论告诉我!

猜你在找的Cocos2d-x相关文章