原创作品,转载请标明http://blog.csdn.net/jackystudio/article/details/16958587


CCDictionary在cocos2d-x中被大量的应用,比如CCTexureCache,CCSpriteFramCache等等。

1.实现原理

1.1.uthash

CCDictionary是使用uthash实现的,而过时的CCMutableDictionary则是使用STL实现,就效率而言CCDictionary至少提升了两倍,而且CCDictionary并没有使用C++模版,因此也很容易绑定到脚本。

uthash是一个C/C++的哈希表实现,它以宏定义的方式实现了哈希表,不仅加快了运行速度,而且与key类型无关。它的github地址是https://github.com/troydhanson/uthash。cocos2d-x的头文件在\cocos2d-x-2.2.0\cocos2dx\support\data_support\uthash.h。

如果想在C++中直接使用也很简单,userguide在这里:http://troydhanson.github.io/uthash/userguide.html。可以很方便地进行增加,删除,查找,计数,迭代,排序等操作。

1.2.键(key)

uthash支持4种标准类型的键:整型,字符串,指针和结构体,不过到了CCDictionary就只支持整型和字符串型了。

[cpp] view plaincopy
  1. enum CCDictType
  2. {
  3. kCCDictUnknown = 0,
  4. kCCDictStr,
  5. kCCDictInt
  6. };

2.CCDictElement

在了解CCDictionary之前还要看一下CCDictElement,很明显,CCDictElement是CCDictionary的一个元素,包含了一个key-value。key支持整型和字符串,使用的时候要注意在同一个CCDictionary中key类型必须要一致,value可以不一致。

3.API

3.1.创建

[cpp] view plaincopy
  1. //创建一个CCDictionary
  2. static CCDictionary* create();
  3. //用一个已存在的CCDictionary来创建一个新的CCDictionary
  4. static CCDictionary* createWithDictionary(CCDictionary* srcDict);
  5. //用一个plist来创建CCDictionary
  6. static CCDictionary* createWithContentsOfFile(const char *pFileName);
  7. //返回一个非autorelease对象的CCDictionary,它讷讷感够确保在新线程中使用
  8. //但是你必须手动管理它的生命周期,当你不再需要它的时候,必须调用CC_SAFE_RELEASE
  9. static CCDictionary* createWithContentsOfFileThreadSafe(const char *pFileName);

3.2.查找

[cpp] view plaincopy
  1. //返回指定字符串类型key的value,如果CCDictionary的key是整型,会出现断言
  2. CCObject* objectForKey(const std::string& key);
  3. //返回指定整型key的value,如果CCDictionary的key是字符串型,会出现断言
  4. CCObject* objectForKey(intptr_t key);
  5. //返回指定字符串类型key的CCString,这里假定value是CCString型,如果不是或者未找到,则返回空串
  6. const CCString* valueForKey(const std::string& key);
  7. //返回指定整型类型key的CCString,这里假定value是CCString型,如果不是或者未找到,则返回空串
  8. const CCString* valueForKey(intptr_t key);

3.3.增加

[cpp] view plaincopy
  1. //插入一个key-value,如果是第一次调用,那么CCDictionary的key类型会被确定为字符串型,之后就不能插入整型key
  2. //如果已存在该key,则旧key-value会被释放和移除,被新的替代
  3. void setObject(CCObject* pObject, const std::string& key);
  4. //插入一个key-value,如果是第一次调用,那么CCDictionary的key类型会被确定为整型,之后就不能插入字符串型key
  5. //如果已存在该key,则旧key-value会被释放和移除,被新的替代
  6. void setObject(CCObject* pObject, intptr_t key);

3.4.移除

[cpp] view plaincopy
  1. //移除指定key
  2. void removeObjectForKey(const std::string& key);
  3. void removeObjectForKey(intptr_t key);
  4. //移除一个CCArray中keys
  5. void removeObjectsForKeys(CCArray* pKeyArray);
  6. //通过元素来移除value
  7. void removeObjectForElememt(CCDictElement* pElement);
  8. //移除所有的key-value
  9. void removeAllObjects();

3.5.其他

[cpp] view plaincopy
  1. //返回一个随机元素,这个使用得注意,因为value可以不一样,所以返回类型每次都可能不同,在类型转换的时候要非常小心
  2. CCObject* randomObject();
  3. //返回一个包含所有key的CCArray
  4. CCArray* allKeys();
  5. //返回指定value的所有key,因为value是可以相同的,内部使用==比较两个value是否相同
  6. CCArray* allKeysForObject(CCObject* object);
  7. //返回元素个数
  8. unsigned int count();
  9. //把CCDictionary写到一个plist中,写入的value要求是字符串型
  10. bool writeToFile(const char *fullPath);

4.示例

[cpp] view plaincopy
  1. // Create a dictionary, return an autorelease object.
  2. CCDictionary* pDict = CCDictionary::create();
  3. // Insert objects to dictionary
  4. CCString* pValue1 = CCString::create("100");
  5. CCString* pValue2 = CCString::create("120");
  6. CCInteger* pValue3 = CCInteger::create(200);
  7. pDict->setObject(pValue1, "key1");
  8. pDict->setObject(pValue2, "key2");
  9. pDict->setObject(pValue3, "key3");
  10. // Get the object for key
  11. CCString* pStr1 = (CCString*)pDict->objectForKey("key1");
  12. CCLog("{ key1: %s }", pStr1->getCString());
  13. CCInteger* pInteger = (CCInteger*)pDict->objectForKey("key3");
  14. CCLog("{ key3: %d }", pInteger->getValue());
  15. CCString* pStr3=static_cast<CCString*>(pDict->randomObject());//这里有问题了,因为value有不同类型,所以随机返回时类型处理要小心
  16. CCLog("{ random key: %s }",pStr3->getCString());              //如果返回的是整型pValue3,那么会出现断言
  17. if(pDict->writeToFile("pdic.plist"))                          //整型的value无法写入,会提示This type cannot appear in property list
  18. CCLog("Write to file success!");

Resource/pdic.plist

[html] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"/>
  3. <plist version="1.0">
  4. <dict>
  5. <key>key1</key>
  6. <string>100</string>
  7. <key>key2</key>
  8. <string>120</string>
  9. <key>key3</key>          <!key3对应整型数据无法写入/>
  10. </dict>
  11. </plist>

5.CCDICT_FOREACH

5.1.概况

宏定义,用于遍历CCDictionary的value。

[cpp] view plaincopy
  1. #define CCDICT_FOREACH(__dict__, __el__) \
  2. CCDictElement* pTmp##__dict__##__el__ = NULL; \
  3. if (__dict__) \
  4. HASH_ITER(hh, (__dict__)->m_pElements, __el__, pTmp##__dict__##__el__)

5.2.示例

[cpp] view plaincopy
  1. CCDictElement* pElement;
  2. CCDICT_FOREACH(dict, pElement)
  3. {
  4. const char*key = pElement->getStrKey();
  5. // You certainly know the type of value, so we assume that it's a CCSprite.
  6. CCSprite* pSprite = (CCSprite*)pElement->getObject();
  7. // ......
  8. }

【玩转cocos2d-x之二十六】数据结构CCDictionary相关推荐

  1. 【Microsoft Azure 的1024种玩法】二十六. 在Azure VM中手动部署Windows Admin Center管理平台

    [简介] Windows Admin Center是微软开发的一套可以部署在本地基于浏览器的GUI的工具集平台,其平台可用于管理Windows相关服务器和PC机器,我们可以利用Windows Admi ...

  2. OpenCV学习笔记(二十六)——小试SVM算法ml OpenCV学习笔记(二十七)——基于级联分类器的目标检测objdect OpenCV学习笔记(二十八)——光流法对运动目标跟踪Video Ope

    OpenCV学习笔记(二十六)--小试SVM算法ml 总感觉自己停留在码农的初级阶段,要想更上一层,就得静下心来,好好研究一下算法的东西.OpenCV作为一个计算机视觉的开源库,肯定不会只停留在数字图 ...

  3. 计算机网络教程网线制作,图吧小白教程 篇二十六:手把手教你自制网线(夹网线水晶头)...

    图吧小白教程 篇二十六:手把手教你自制网线(夹网线水晶头) 2019-11-19 23:07:38 31点赞 309收藏 27评论 创作立场声明:咕咕咕 教程最后还是出了,不过咱现在用啥还是直接网购号 ...

  4. (转)tensorflow入门教程(二十六)人脸识别(上)

    https://blog.csdn.net/rookie_wei/article/details/81676177 1.概述 查看全文 http://www.taodudu.cc/news/show- ...

  5. 如何选择适合你的兴趣爱好(二十六),剪纸

    如何选择适合你的兴趣爱好(二十六),剪纸 围城网的摇摇今天给大家带来了"如何选择适合你的兴趣爱好"系列专辑的第二十六讲--剪纸. 剪纸又叫刻纸,窗花或剪画,是一种用剪刀或刻刀在纸上 ...

  6. BetaFlight模块设计之二十六:接收机任务分析

    BetaFlight模块设计之二十六:接收机任务分析 接收机任务 配置情况 硬件配置 软件配置 驱动配置 sbus驱动函数分析 sbusDataReceive函数 sbusFrameStatus函数 ...

  7. 2021年大数据Hadoop(二十六):YARN三大组件介绍

    全网最详细的Hadoop文章系列,强烈建议收藏加关注! 后面更新文章都会列出历史文章目录,帮助大家回顾知识重点. 目录 本系列历史文章 前言 Yarn三大组件介绍 ResourceManager No ...

  8. 模板方法模式 Template method 行为型 设计模式(二十六)

    模板方法模式 Template method 上图为网上百度的一份简历模板截图 相信大家都有求职的经历,那么必然需要简历,写简历的时候,很可能你会网上检索一份简历模板,使用此模板的格式,然后替换为你的 ...

  9. 窗口消息——Windows核心编程学习手札之二十六

    窗口消息 --Windows核心编程学习手札之二十六 Windows允许一个进程至多建立10000个不同类型的用户对象(user object):图符.光标.窗口类.菜单.加速键表等,当一个线程调用一 ...

  10. 2008R2Win7管理二十六ADRMS客户端使用及侦错

    2008R2Win7管理二十六ADRMS客户端使用及侦错 预计我以后都没太多时间专研新技术和写文啦,尽量挤时间吧,有一篇放一篇吧,呵呵 本篇介绍在win7客户端使用adrms来进行权限管理和侦错,在使 ...

最新文章

  1. MNE-Python专辑 | MNE-Python详细安装与使用(更新)
  2. python读取数据库之给变量_使用Python和SQLite,如何将数据库中的项读入变量?
  3. Java一个对象的内存运行流程图
  4. java面试题二十五 构造函数
  5. 零基础学python裴帅帅_人工智能时代,爬虫如此简单。
  6. 历届试题 大臣的旅费(深搜 树的直径)
  7. .NET 开源项目 StreamJsonRpc 介绍[上篇]
  8. Android插件化开发之动态加载技术系列索引
  9. [改善Java代码]若有必要,使用变长数组
  10. php cgi漏洞,Nginx + PHP CGI的一个可能的安全漏洞
  11. Python机器学习:逻辑回归001什么是逻辑回归
  12. php form 添加滚动条,element 使用总结(1. tree使用 2. table修改滚动条样式 3. el-form 自定义label添加icon)...
  13. (四)洞悉linux下的Netfilteriptables:包过滤子系统iptable_filter
  14. python中randint用法_python中的randint,引入模块
  15. QQ概念版酿杯具,头条下载竟是病毒
  16. wamp php不可用_PHPWAMP开启php
  17. 大数据还是人工智能?哪个发展更好
  18. spark.reducer.maxReqsInFlight和spark.reducer.maxBlocksInFlightPerAddress
  19. 【路径规划】基于粒子群算法机器人避障路径规划matlab代码
  20. 植物大战僵尸——最强阵容

热门文章

  1. 循环结构_while循环
  2. ES6新特性之修饰器
  3. CSDN博主排名更新公告
  4. Eureka常用配置详解
  5. Nginx_负载均衡配置讲解
  6. jvm_虚拟机组成部分概述
  7. 学计算机所需要的英语单词,学计算机最少要懂的英语单词是什么
  8. Linux Capabilities 入门教程--进阶实战篇
  9. from mysql_MySQL的FROM
  10. pytorch教程龙曲良41-45