CCArray

CCArray

简介

CCArray是cocos2d鼎力支持的数据结构类。它对游戏存储数组型数据做了优化。你可以在Cocos2d-x源文件目录cocos2d/support/ data_support里面找到CCArray的实现。CCArray在cocos2d内被使用广泛,它模拟了苹果NSMutableArray的功能,但是执行效率更高。

CCArray是一个面向对象包装类

CCArray继承至CCObject(CCObject主要是为了自动内存管理而创建的),并且提供了一系列接口,包括

创建

    /** 创建一个数组 */
    static CCArray* create();
     /** 使用一些对象创建数组 */
    static CCArray* create(CCObject* pObject, …);
     /** 使用一个对象创建数组 */
    static CCArray* createWithObject(CCObject* pObject);
     /** 创建一个指定大小的数组 */
    static CCArray* createWithCapacity(unsigned int capacity);
     /** 使用一个现有的CCArray数组来新建一个数组 */
    static CCArray* createWithArray(CCArray* otherArray);

插入

    /** 插入一个对象 */
    void addObject(CCObject* object);
    /** 插入别外一个数组里面的全部对象 */
    void addObjectsFromArray(CCArray* otherArray);
    /** 在一个确定的索引位置插入一个对象 */
    void insertObject(CCObject* object, unsigned int index);

删除

    /** 移除最后的一个对象 */
    void removeLastObject(bool bReleaseObj = true);
    /**移除一个确定的对象 */
    void removeObject(CCObject* object, bool bReleaseObj = true);
    /** 移除一个确定索引位置的元素 */
    void removeObjectAtIndex(unsigned int index, bool bReleaseObj = true);
    /** 移除全部元素 */
    void removeObjectsInArray(CCArray* otherArray);
    /** 移除所有对象 */
    void removeAllObjects();
    /** 快速移除一个对象 */
    void fastRemoveObject(CCObject* object);
    /** 快速移除一个确定索引位置的对象 */
    void fastRemoveObjectAtIndex(unsigned int index);

remove和fastRemove有什么区别,可以看看源代码,remove是从CCArray中完全的移除,fastRemove只是将CCArray中对应的对象释放掉了,没够改变整个CCArray的结构。从代码上来看,区别在于删除元素之后,是否把数组之后的元素向前移动覆盖掉之前位置的元素。 代码上的差别如下所示:

    unsigned int remaining = arr->num - index;
    if(remaining>0)
    {
        memmove((void *)&arr->arr[index], (void *)&arr->arr[index+1], remaining * sizeof(CCObject*));
    }

遍历

CCArray

在教程第五章 “怎么样去侦测碰撞”中,在update()函数下面调用了CCARRAY_FOREACH(arr, obj)方法,这个方法就是用来遍历CCArray(_targets和_projectiles),用来在每一帧中检测碰撞。

在HelloWorldScene.h中申明,并且在HelloWorldScene.cpp中定义

    void HelloWorld::update(ccTime dt)
    {
        CCArray *projectilesToDelete = new CCArray;
        CCObject* it = NULL;
        CCObject* jt = NULL;

     CCARRAY_FOREACH(_projectiles, it)
     {
      CCSprite *projectile = dynamic_cast(it);
      CCRect projectileRect = CCRectMake(
       projectile->getPosition().x - (projectile->getContentSize().width/2),
       projectile->getPosition().y - (projectile->getContentSize().height/2),
       projectile->getContentSize().width,
       projectile->getContentSize().height);

      CCArray* targetsToDelete =new CCArray;

            CCARRAY_FOREACH(_targets, jt)
      {
       CCSprite *target = dynamic_cast(jt);
       CCRect targetRect = CCRectMake(
        target->getPosition().x - (target->getContentSize().width/2),
        target->getPosition().y - (target->getContentSize().height/2),
        target->getContentSize().width,
        target->getContentSize().height);

       // if (CCRect::CCRectIntersectsRect(projectileRect, targetRect))
                if (projectileRect.intersectsRect(targetRect))
       {
        targetsToDelete->addObject(target);
       }
      }

            CCARRAY_FOREACH(targetsToDelete, jt)
      {
       CCSprite *target = dynamic_cast(jt);
       _targets->removeObject(target);
       this->removeChild(target, true);
        }

        if (targetsToDelete->count() >0)
        {
          projectilesToDelete->addObject(projectile);
        }
        targetsToDelete->release();
      }

        CCARRAY_FOREACH(projectilesToDelete, it)
     {
      CCSprite* projectile = dynamic_cast(it);
      _projectiles->removeObject(projectile);
      this->removeChild(projectile, true);
     }
    projectilesToDelete->release();
    }

CCArray 和 NSArray

CCArray效率很高,但是CCArray中的对象也是有对应位置的,假如你的代码依赖于这些对象的位置,你就不应该使用fastRemoveObject方法。

速度测试

以下代码是测试CCArray和NSArray分别遍历200个对象:

测试A(NSArray)

    for(int w = 0; w<100; w++){
       for(id object in arrayNS){
           //Do something
     }
    }

测试B(CCArray)

    ccArray *arrayData = array->data;
    id object;
    int nu = arrayData->num;
    for(int w = 0; w<100; w++){
        CCARRAY_FOREACH(arrayData, object){
           object = arrayData->arr[i];
          //Do something
       }
    }

结果

以上测试表明在遍历数组的时候,CCArray比NSArray在性能上提升了大概10%。在使用CCARRAY_FOREACH和NSArray快速枚举来迭代整个数组也是有些微的性能改善。当使用快速枚举的时候,这两种方式的数组和相同领域中的C数组基本上有相同的性能表现,而且CCArray相比纯C数组有极其细微的性能提升。

使用注意事项

CCArray一般不会被增加到其他类中,所以他的引用计数是1,并且设置为autorelease对象。创建CCArray对象并且retain,然后在这个类中的析构函数中调用release方法来释放内存。

如果CCObject对象添加到CCArray中,那么CCObject对象的引用计数将会加1.

时间: 2024-11-01 14:11:04

CCArray的相关文章

cocos2d-x 之 CCArray 源码分析

cocos2d-x 自己实现了一个数组CCArray ,下面我们来分析一下CCArray的源码 CCArray继承CCObject,所以,CCArray也具有引用计数功能和内存自动管理功能. 数组的源码如下: class CC_DLL CCArray : public CCObject { public: /************************************************************************/ /* 构造析构函数 */ /*******

1.cocos2dx内存管理和CCArray,CCMenuItem

1 C++内存管理 A 栈上的空间 自生自灭,不用管理 B 堆上的空间 手动new,手动delete,否则产生内存泄漏 2 内存管理的难处 管理原则,谁申请谁释放 3 内存的智能管理 主要有两种实现智能管理内存的技术,一种是引用计数,一是垃圾回收. 引用计数:通过给每个对象维护一个引用计数器,记录该对象当前被引用的次数.当对象增加一次引用时,计数器加1:而对象失去一次引用时,计数器减1:当引用计数为0 时,标志着该对象的生命周期结束,自动触发对象的回收释放.引用计数解决了对象的生命周期管理问题,

7.数据本地化CCString,CCArray,CCDictionary,tinyxml2,写入UserDefault.xml文件,操作xml,解析xml

 数据本地化 A CCUserDefault 系统会在默认路径cocos2d-x-2.2.3\projects\Hello\proj.win32\Debug.win32下生成一个名为UserDefault.xml.所有的key皆为char *型,value类型为bool intfloat double std::string. 读操作 bool getBoolForKey(const char* pKey); bool getBoolForKey(const char* pKey, bool

cocos2d-x CCArray使用中避免出现野指针问题

问题及现象 此前,调试cocos2d-x + CocoStudio游戏程序过程中遇到一个运行时错误.通过调用堆栈来看,错误指针停在~CCNodeRGBA(). 分析1 CCNodeRGBA是一个继承自CCNode的子类,其主要是增加了与结点透明度相关的属性控制功能. class CC_DLL CCNodeRGBA : public CCNode, public CCRGBAProtocol CCNodeRGBA是CCSprite和Widget(即UIWidget)的直接父类.因此,出现错误对象应

cocos2d-实现读取.plist文件(使用数组CCArray)

学习札记之cocos2d-x2.1.1实现读取.plist文件(使用数组CCArray) [html] view plaincopyprint? <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dt

cocos2d::Vector

v3.0 beta加入 定义在"COCOS2DX_ROOT/cocos/base"的"CCVector.h"头文件中. template<class T>class CC_DLL Vector; cocos2d::Vector<T>是一个封装好的能动态增长顺序访问的容器. cocos2d::Vector<T>中的元素是按序存取的,它的低层实现数据结构是标准模版库中的标准顺序容器std::vector. 在Cocos2d-x v3.

Cocos2d-X使用CCScrollView创建滚动视图

CCScrollView可以使游戏有滚动视图的效果,并且可以通过滚动视图切换游戏场景,滚动视图常用于游戏中选择关卡 实例1:使用CCScrollView创建一个简单的滚动视图 首先创建一个ScrollView类 然后在ScrollView.h中添加下面的代码 #ifndef __ScrollView_H__ #define __ScrollView_H__ #include "cocos2d.h" #include "cocos-ext.h" USING_NS_CC

Cocos2d-x 3.x plist+png 做动画

***************************************转载请注明出处:http://blog.csdn.net/lttree****************************************** 前言: 这次的东西,其实是在做完2048后,我有个Flash想用. 就像,天天系列,开头会有 "提米" 的叫声+动画, 是不是感觉很带感. 之前,做第一个游戏的时候,有做一套78帧的Flash, 但是当时不会用,现在正好拿过来用了,嘿嘿~ 正文: 这次例子

quick-cocos2d-x游戏开发【8】——动画与动作

动画与动作,在quick中都有对其封装,所以我们还是来看一下吧. 总的来说,对于帧动画,quick封装的方法我们可以经常使用,这是非常方便的,下面直接上代码来直观感受下, 比如,14张帧图片,采用cocos2d-x lua的方法来写是这样的, local sp = display.newSprite("grossini_dance_01.png", display.cx, display.cy) self:addChild(sp) local animation = CCAnimati