cocos2dx学习笔记:CCArray-removeObjectAtIndex

前端之家收集整理的这篇文章主要介绍了cocos2dx学习笔记:CCArray-removeObjectAtIndex前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

http://cstriker1407.info/blog/cocos2dx-study-notes-ccarray/

最近学习了下CCArray,想看下它的内部实现,搞清楚存储方式,以便后面使用起来更高效。

打开CCArray的源码,看了下,发现它其实内部是数组的实现形式,而且CCArray的所有函数只是包装了下ccArray的实现。

@H_301_12@
CCArray.h:
@H_301_12@
@H_301_12@
class CC_DLL CCArray : public CCObject
@H_301_12@
{
@H_301_12@
public:
@H_301_12@
staticCCArray* create();
@H_301_12@
。。。。。
@H_301_12@
。。。。。
@H_301_12@
public:
@H_301_12@
ccArray* data;
@H_301_12@
。。。。。
@H_301_12@
。。。。。
@H_301_12@
};

通过.h文件可以发现,CCArray的所有操作其实最后都是操作的它的变量data,这个变量data的类型为ccArray,它是个结构体,真正的实现了Array的各种方法

@H_301_12@
ccCArray.h:
@H_301_12@
typedef struct _ccArray {
@H_301_12@
unsignedint num,max;
@H_301_12@
CCObject** arr;
@H_301_12@
} ccArray;
@H_301_12@
@H_301_12@
/** Allocates and initializes a new array with specified capacity */
@H_301_12@
ccArray* ccArrayNew(unsigned int capacity);
@H_301_12@
/** Frees array after removing all remaining objects. Silently ignores nil arr. */
@H_301_12@
void ccArrayFree(ccArray*& arr);
@H_301_12@
/** Doubles array capacity */
@H_301_12@
void ccArrayDoubleCapacity(ccArray *arr);
@H_301_12@
。。。。。。
@H_301_12@
。。。。。。

到这里就很清楚了,ccArray是一个结构体,里面封装了一个数组的指针。因此通过CCArray进行的各种操作其实内部是操作的一个数组指针
那么就很容易的得出结论:

1)随机查找和修改的速度很快。
2)在指定的位置插入和删除元素速度很慢。
3)扩容消耗很大。

后续使用时要注意。不过个人感觉cocos2dx代码中仍然有问题,那就是替换:

@H_301_12@
void CCArray::replaceObjectAtIndex(unsigned intindex,CCObject* pObject,boolbReleaSEObject/* = true*/)
@H_301_12@
{
@H_301_12@
ccArrayInsertObjectAtIndex(data,pObject,index);
@H_301_12@
ccArrayRemoveObjectAtIndex(data,index+1);
@H_301_12@
}
@H_301_12@
@H_301_12@
ccCArray.cpp:
@H_301_12@
/** Inserts a value at a certain position. Behavior undefined if array doesn't have enough capacity */
@H_301_12@
void ccCArrayInsertValueAtIndex( ccCArray *arr,void* value,unsignedint index)
@H_301_12@
{
@H_301_12@
CCAssert( index < arr->max,"ccCArrayInsertValueAtIndex: invalid index");
@H_301_12@
@H_301_12@
unsignedint remaining = arr->num - index;
@H_301_12@
// make sure it has enough capacity
@H_301_12@
if(arr->num + 1 == arr->max)
@H_301_12@
{
@H_301_12@
ccCArrayDoubleCapacity(arr);
@H_301_12@
}
@H_301_12@
// last Value doesn't need to be moved
@H_301_12@
if( remaining > 0) {
@H_301_12@
// tex coordinates
@H_301_12@
memmove((void*)&arr->arr[index+1],(void*)&arr->arr[index],sizeof(void*) * remaining );
@H_301_12@
}
@H_301_12@
@H_301_12@
arr->num++;
@H_301_12@
arr->arr[index] = value;
@H_301_12@
}
@H_301_12@
@H_301_12@
/** Removes object at specified index and pushes back all subsequent objects.
@H_301_12@
Behavior undefined if index outside [0,num-1]. */
@H_301_12@
void ccArrayRemoveObjectAtIndex(ccArray *arr,unsigned intindex,boolbReleaSEObj/* = true*/)
@H_301_12@
{
@H_301_12@
CCAssert(arr && arr->num > 0 && index < arr->num,"Invalid index. Out of bounds");
@H_301_12@
if(bReleaSEObj)
@H_301_12@
{
@H_301_12@
CC_SAFE_RELEASE(arr->arr[index]);
@H_301_12@
}
@H_301_12@
@H_301_12@
arr->num--;
@H_301_12@
@H_301_12@
unsignedint remaining = arr->num - index;
@H_301_12@
if(remaining>0)
@H_301_12@
{
@H_301_12@
memmove((void*)&arr->arr[index],(void*)&arr->arr[index+1],remaining * sizeof(CCObject*));
@H_301_12@
}
@H_301_12@
}
@H_301_12@
@H_301_12@
void ccArrayDoubleCapacity(ccArray *arr)
@H_301_12@
{
@H_301_12@
arr->max *= 2;
@H_301_12@
CCObject** newArr = (CCObject**)realloc( arr->arr,arr->max *sizeof(CCObject*) );
@H_301_12@
// will fail when there's not enough memory
@H_301_12@
CCAssert(newArr != 0,"ccArrayDoubleCapacity Failed. Not enough memory");
@H_301_12@
arr->arr = newArr;
@H_301_12@
}

通过上述代码可以发现,移除,插入,扩容都有内存操作,因此最好在使用CCArray时考虑好初始容量。

另外,CCArray为了提供更快速删除功能增加方法 fastremove*,这里分析下实现:

@H_301_12@
void ccArrayFastRemoveObjectAtIndex(ccArray *arr,unsigned intindex)
@H_301_12@
{
@H_301_12@
CC_SAFE_RELEASE(arr->arr[index]);
@H_301_12@
unsignedint last = --arr->num;
@H_301_12@
arr->arr[index] = arr->arr[last];
@H_301_12@
}

根据代码可知,快速删除的实质是将数组的最后一个元素添加到这个空缺来,这样就要注意的是数组内部的顺序已经变了
测试代码如下:

@H_301_12@
CCArray *arr = CCArray::createWithCapacity(5);
@H_301_12@
arr->addObject(CCString::create("A"));
@H_301_12@
arr->addObject(CCString::create("B"));
@H_301_12@
arr->addObject(CCString::create("C"));
@H_301_12@
arr->addObject(CCString::create("D"));
@H_301_12@
arr->addObject(CCString::create("E"));
@H_301_12@
@H_301_12@
CCLOG("init");
@H_301_12@
CCObject *itemStr = NULL;
@H_301_12@
CCARRAY_FOREACH(arr,itemStr)
@H_301_12@
{
@H_301_12@
CCLOG("%s",((CCString *)itemStr)->getCString());
@H_301_12@
}
@H_301_12@
@H_301_12@
CCLOG("fast remove");
@H_301_12@
arr->fastRemoveObjectAtIndex(2);
@H_301_12@
CCARRAY_FOREACH(arr,itemStr)
@H_301_12@
{
@H_301_12@
CCLOG("%s",((CCString *)itemStr)->getCString());
@H_301_12@
}

输出

@H_301_12@
init
@H_301_12@
A
@H_301_12@
B
@H_301_12@
C
@H_301_12@
D
@H_301_12@
E
@H_301_12@
fast remove
@H_301_12@
A
@H_301_12@
B
@H_301_12@
E
@H_301_12@
D

如下图:

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