Cocos2d-x中的数组类CCArray深入分析

2023-11-10

 前面的博文中我们提到了一个词典类CCDictionary,它和数组类CCArray共称Cocos2d-x两大常用数据结构,因为在项目中数组类 CCArray我们使用的实在是太多了,因此这里补充一篇关于CCArray深入分析的博文,其中提到了一个很多新手可能没有使用过的类ccCArray类,CCArray内部其实都是通过调用该类实现的,值得我们注意。




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


1.API

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

1.1.创建

1
2
3
4
5
6
7
8
9
10
//创建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.添加

1
2
3
4
5
6
//添加一个元素
void  addObject(CCObject* object);
//添加一个已存在array中所有元素
void  addObjectsFromArray(CCArray* otherArray);
//在指定位置插入元素
void  insertObject(CCObject* object, unsigned  int  index);

1.3.删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//移除最后一个元素
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.操作元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//返回元素个数
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内容

1
2
3
4
5
6
7
8
9
10
//交换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.普通删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//普通删除
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.快速删除

1
2
3
4
5
6
7
8
9
10
//快速删除
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中容量和个数并不是同一个概念。个数<=容量。从添加元素的源码中可以看到在添加之前会先进行空间分配,所以它是一个动态分配内存的过程。如下

1
2
3
4
5
6
7
void  ccArrayEnsureExtraCapacity(ccArray *arr, unsigned  int  extra) //确保有额外的空间
{
     while  (arr->max < arr->num + extra) //判断空间是否足够
     {
         ccArrayDoubleCapacity(arr); //增加一倍空间
     }
}

所以,每次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元素

1
2
3
4
5
6
7
8
9
10
11
#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来释放内存。真心想吐槽。。。


FROM: http://blog.csdn.net/huanghuanghbc/article/details/25335369





本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Cocos2d-x中的数组类CCArray深入分析 的相关文章

  • 一个http请求的详细过程---理解计算机网络

    很久没来这个博客了 仍记得当时开辟这个博客就是为了今年找工作的 转眼间 我已经在寻找工作了 数据结构 网络系统 C C 数据库等等 笔试经常遇到 国庆之前 海辉和阿里巴巴就过来了 还给了面试通知 可惜我没去 国庆之后 从家里过来后 笔试倒是
  • Java架构直通车——Java中单体应用锁的局限性&分布式锁

    文章目录 前言 单体应用锁的局限性 什么是分布式锁 目前存在的分布式的方案 前言 通过之前的并发编程的学习 对JAVA中的锁有了深刻的理解 前面内容中讲到的锁都是有JDK官方提供的锁的解决方案 也就是说这些锁只能在一个JVM进程内有效 我们
  • TensorFlow:实战Google深度学习框架,数据增强

    在 TensorFlow 实战Google深度学习框架 一书中 发现一段很好的增强图像数据样本数量的方法 和大家分享下 import matplotlib pyplot as plt def distort color image colo
  • 单元三:阻抗匹配(电容电感,变压器,传输线变压器,附带硬件电路)

    本文是针对阻抗匹配介绍的 如果感兴趣 想要详细咨询问题或者想要参考资料可以详细咨询博主 B站对应讲解本文链接 对于全桥逆变这种高频大功率电路 如果其输出阻抗与负载阻抗不匹配 那么全桥逆变电路输出的能量将不能有效的传输给负载 严重时所输出的能

随机推荐

  • 感抗的计算方式

    感抗的计算方式 2011 01 12 17 20 15903437087 分类 物理学 浏览6763次 网友采纳 2011 01 12 17 23 2 fL 交流电也可以通过线圈 但是线圈的电感对交流电有阻碍作用 这个阻碍叫做感抗 交流电越
  • 【华为OD机试】树状结构查询【2023 B卷

    华为OD机试 真题 点这里 华为OD机试 真题考点分类 点这里 题目描述 通常使用多行的节点 父节点表示一棵树 比如 西安 陕西 陕西 中国 江西 中国 中国 亚洲 泰国 亚洲 输入一个节点之后 请打印出来树中他的所有下层节点 输入描述 第
  • 使用Unity3D开发一款VR弹球游戏

    作者简介 沈庆阳 JackFlynn 拥有多年Unity3D开发经验 于2014年接触并开发VR应用 现泰然网虚拟现实教程组核心成员 撰写了 虚拟现实游戏开发 系列教程 开发VR游戏首先要选择一个合适的平台 目前可供选择的平台不多 Goog
  • AI助力多文档审查丨合同风险审查、招投标文件、合同和中标通知书一致性审查

    当下 企业管理的数据和文档管理中充斥着大量有复用价值的数据 资料和内容性信息 每一家企业都有许多商业文档和法律文档需要使用和维护 其中包含了不同语言文字 手写体 数字 公式等 然而 目前企业的各种文档资料仍主要依靠人工手段进行核心内容的阅读
  • leetcode462. 最小操作次数使数组元素相等 II(中等)

    思路 目标是中位数 class Solution public int minMoves2 vector
  • PID算法(三)串级PID

    串级PID 如果说前一次的衍生PID 是在基础PID算法的横向上变形的话 那本片的串级PID就是在基础PID的算法上 做纵向的嵌套 与单级PID的不同 与单级PID不同的是 串级PID 需要两个实际值输入 其中内层的变量 是外层变量的一次导
  • 第七章:借阅管理【基于Servlet+JSP的图书管理系统】

    借阅管理 1 借书卡 1 1 查询借书卡 借书卡在正常的CRUD操作的基础上 我们还需要注意一些特殊的情况 查询信息的时候 如果是管理员则可以查询所有的信息 如果是普通用户则只能查看自己的信息 这块的控制在登录的用户信息 然后就是在Dao中
  • C++的MFC,与C#的.NET

    1 MFC早已过时 现在C 多数是用来编写底层方法而不是开发桌面程序 桌面程序有Delphi 其控件库比MFC要多 微软早不维护MFC了 2 MFC学习曲线的陡峭是众所周知的 主要难点在于C 语言本身 和MFC使用了大量的宏和怪异的语法 主
  • 段页式存储管理

    内存管理有三种 页式管理 段式管理和段页式管理 1 页式管理 页式管理是用户程序的地址空间被划分成若干固定大小的区域 称为 页 相应地 内存空间分成若干个实际的物理块 页和块的大小相等 可将用户程序的任一页放在内存的任一块中 实现了离散分配
  • OpenCV C++人脸识别

    OpenCV C 人脸识别 程序说明 代码 运行效果 程序说明 程序描述 来自OpenCV安装目录下Samples文件夹中的官方示例程序 人脸识别 源码路径 opencv sources samples cpp tutorial code
  • 【计算机网络】运输层:为什么TCP建立连接第一个SYN报文要消耗一个序号呢?

    TCP在建立连接时要发送的第一个SYN报文段是一个控制报文段 其主要目的是为了和对方建立同步 并明确自己采用的初始序号 这个报文段没有数据 但是这个SYN报文段非常重要 不允许丢失 传错了或丢失了就要重传 否则无法建立连接 这就必须进行编号
  • 模板类的开发

    模板类的开发 栈 定长数组 变长数组 栈 入栈和出栈使用引用是为了传递参数 注意构造函数初始化列表使用模板的写法 注意析构函数delete指针需要 测试 定长数组 重载了括号运算符 调用的其实是数组 使用int 使用char 变长数组
  • GuLi商城-项目初始结构创建,GitHub仓库创建

    GitHub账号和密码 账号 11360XXXXX qq com 密码 ZH SH 19 1016 新建仓库 gulimall 记得勾选下Add a README file 上面忘记勾选了 实际建议还是要勾选下 复制路径 打开IDEA检出项
  • eclipse中配置Tomcat

    将Tomcat服务器整合到Eclipse工具中 可以通过Eclipse启动 关闭tomcat服务器 更重要的是 可以非常方便的将在Eclipse中创建的Web项目发布到Tomcat服务器中运行 文章目录 在这里插入图片描述 方式一 在win
  • 使用python查询Elasticsearch并导出所有数据

    作为数据分析师 要学的可真多 但一旦触及到数据 无论它在藏在哪里 只要我们想要使用 就真是无所不用其极阿 python刀操起来 刚开始一直通过Kibana提供的工具来查询存储在Elasticsearch中的数据 统计个结果完全没问题 偶一日
  • L2-002. 链表去重

    给定一个带整数键值的单链表L 本题要求你编写程序 删除那些键值的绝对值有重复的结点 即对任意键值K 只有键值或其绝对值等于K的第一个结点可以被保留 同时 所有被删除的结点必须被保存在另外一个链表中 例如 另L为21 15 15 7 15 则
  • 2019 MySQL 8 安全安装避坑指南

    1 安装vmware centos的虚拟机 省却安装vmware虚拟机管理的部分 centos7下载地址 官方 https www centos org download 镜像文件地址 http mirrors nju edu cn cen
  • Mathmatic 函数表

    一 运算符及特殊符号 Line1 执行Line 不显示结果 Line1 line2 顺次执行Line1 2 并显示结果 name 关于系统变量name的信息 name 关于系统变量name的全部信息 command 执行Dos命令 n N的
  • gdal读取tif常用函数

    读入文件 dataset gdal open filename 获取数据 dataset GetDescription 获得栅格的描述信息 dataset RasterCount 获得栅格数据集的波段数 band dataset GetRa
  • Cocos2d-x中的数组类CCArray深入分析

    前面的博文中我们提到了一个词典类CCDictionary 它和数组类CCArray共称Cocos2d x两大常用数据结构 因为在项目中数组类 CCArray我们使用的实在是太多了 因此这里补充一篇关于CCArray深入分析的博文 其中提到了