原創作品,轉載請標明:http://blog.csdn.net/jackystudio/article/details/16938787
CCArray是從cocos2d中移植過來的,類似於Apple的NSMutableArray,但是比NSMutableArray更爲的好用。要注意的是雖然CCArray和CCDictionary可以管理cocos2d-x中絕大多數的類,但是仍然無法替代STL庫,STL庫更爲強有力。
1.API
先看一下CCArray可以幫我們做什麼。
1.1.創建
- //創建array
- static CCArray* create();
- //使用一系列CCObject創建array
- static CCArray* create(CCObject* pObject, …);
- //使用一個CCObject創建array
- static CCArray* createWithObject(CCObject* pObject);
- //創建array並設置容量
- static CCArray* createWithCapacity(unsigned int capacity);
- //用一個已存在的array創建另一個array
- static CCArray* createWithArray(CCArray* otherArray);
1.2.添加
- //添加一個元素
- void addObject(CCObject* object);
- //添加一個已存在array中所有元素
- void addObjectsFromArray(CCArray* otherArray);
- //在指定位置插入元素
- void insertObject(CCObject* object, unsigned int index);
1.3.刪除
- //移除最後一個元素
- void removeLastObject(bool bReleaseObj = true);
- //移除某個元素
- void removeObject(CCObject* object, bool bReleaseObj = true);
- //移除一個指定位置的元素
- void removeObjectAtIndex(unsigned int index, bool bReleaseObj = true);
- //移除某個array
- void removeObjectsInArray(CCArray* otherArray);
- //移除所有元素
- void removeAllObjects();
- //快速移除某個元素
- void fastRemoveObject(CCObject* object);
- //快速移除某個指定位置的元素
- void fastRemoveObjectAtIndex(unsigned int index);
1.4.操作元素
- //返回元素個數
- unsigned int count() const;
- //返回array容量
- unsigned int capacity() const;
- //返回指定CCObject的位置,如果不存在返回UINT_MAX
- unsigned int indexOfObject(CCObject* object) const;
- //返回指定位置的CCObject
- CCObject* objectAtIndex(unsigned int index);
- //返回最後一個元素
- CCObject* lastObject();
- //返回隨機元素
- CCObject* randomObject();
- //返回某個元素是否存在於array中
- bool containsObject(CCObject* object) const;
- //判斷array是否相等
- bool isEqualToArray(CCArray* pOtherArray);
1.5.操作array內容
- //交換2個元素
- void exchangeObject(CCObject* object1, CCObject* object2);
- //交換2個指定位置元素
- void exchangeObjectAtIndex(unsigned int index1, unsigned int index2);
- //用一個對象替代指定位置元素
- void replaceObjectAtIndex(unsigned int uIndex, CCObject* pObject, bool bReleaseObject = true);
- //反轉array
- void reverseObjects();
- //收縮array內存以匹配元素個數
- void reduceMemoryFootprint();
2.remove和fastremove
從1.3可以看出刪除有兩種方式,普通刪除和快速刪除,它們有什麼區別呢?
2.1.普通刪除
- //普通刪除
- void ccArrayRemoveObjectAtIndex(ccArray *arr, unsigned int index, bool bReleaseObj/* = true*/)
- {
- CCAssert(arr && arr->num > 0 && index < arr->num, "Invalid index. Out of bounds");
- //刪除元素內容,位置仍保留着
- if (bReleaseObj)
- {
- CC_SAFE_RELEASE(arr->arr[index]);
- }
- //長度減1
- arr->num--;
- //獲得要刪除的元素後的元素個數
- unsigned int remaining = arr->num - index;
- if(remaining>0)
- {
- //將要刪除元素後的所有元素逐個向前移動
- memmove((void *)&arr->arr[index], (void *)&arr->arr[index+1], remaining * sizeof(CCObject*));
- }
- }
2.2.快速刪除
- //快速刪除
- void ccArrayFastRemoveObjectAtIndex(ccArray *arr, unsigned int index)
- {
- //刪除元素內容,位置仍保留着
- CC_SAFE_RELEASE(arr->arr[index]);
- //獲取最後一個元素
- unsigned int last = --arr->num;
- //把最後一個元素插到刪除元素的位置上
- arr->arr[index] = arr->arr[last];
- }
2.3.總結
如果有array={0,1,2,3,4,5},如果要刪除3,使用普通刪除得到的結果{0,1,2,4,5},使用快速刪除得到的結果是{0,1,2,5,4}。可以看出快速刪除的效率比普通刪除效率高,就差在移動元素的時間複雜度上。
3.內存分配
3.1.容量和個數
CCArray中容量和個數並不是同一個概念。個數<=容量。從添加元素的源碼中可以看到在添加之前會先進行空間分配,所以它是一個動態分配內存的過程。如下
- void ccArrayEnsureExtraCapacity(ccArray *arr, unsigned int extra)//確保有額外的空間
- {
- while (arr->max < arr->num + extra)//判斷空間是否足夠
- {
- ccArrayDoubleCapacity(arr);//增加一倍空間
- }
- }
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元素
- #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__++)
- #define CCARRAY_FOREACH_REVERSE(__array__, __object__) \
- if ((__array__) && (__array__)->data->num > 0) \
- for(CCObject** __arr__ = (__array__)->data->arr + (__array__)->data->num-1, **__end__ = (__array__)->data->arr; \
- __arr__ >= __end__ && (((__object__) = *__arr__) != NULL/* || true*/); \
- __arr__--)
6.示例
CCArray的使用示例在http://blog.csdn.net/jackystudio/article/details/11917875此文中有比較典型的應用,這裏就不再詳述。
7.注意
一般來說,CCArray不會被add到其他類,所以它的引用計數是1,而且被設置爲自動釋放。所以創建CCArray對象時要記得調用retain,而且在析構的時候也要調用release來釋放內存。真心想吐槽。。。