【玩转cocos2d-x之二十六】数据结构CCDictionary
原创作品,转载请标明: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就只支持整型和字符串型了。
- enum CCDictType
- {
- kCCDictUnknown = 0,
- kCCDictStr,
- kCCDictInt
- };
2.CCDictElement
在了解CCDictionary之前还要看一下CCDictElement,很明显,CCDictElement是CCDictionary的一个元素,包含了一个key-value。key支持整型和字符串,使用的时候要注意在同一个CCDictionary中key类型必须要一致,value可以不一致。
3.API
3.1.创建
- //创建一个CCDictionary
- static CCDictionary* create();
- //用一个已存在的CCDictionary来创建一个新的CCDictionary
- static CCDictionary* createWithDictionary(CCDictionary* srcDict);
- //用一个plist来创建CCDictionary
- static CCDictionary* createWithContentsOfFile(const char *pFileName);
- //返回一个非autorelease对象的CCDictionary,它讷讷感够确保在新线程中使用
- //但是你必须手动管理它的生命周期,当你不再需要它的时候,必须调用CC_SAFE_RELEASE
- static CCDictionary* createWithContentsOfFileThreadSafe(const char *pFileName);
3.2.查找
- //返回指定字符串类型key的value,如果CCDictionary的key是整型,会出现断言
- CCObject* objectForKey(const std::string& key);
- //返回指定整型key的value,如果CCDictionary的key是字符串型,会出现断言
- CCObject* objectForKey(intptr_t key);
- //返回指定字符串类型key的CCString,这里假定value是CCString型,如果不是或者未找到,则返回空串
- const CCString* valueForKey(const std::string& key);
- //返回指定整型类型key的CCString,这里假定value是CCString型,如果不是或者未找到,则返回空串
- const CCString* valueForKey(intptr_t key);
3.3.增加
- //插入一个key-value,如果是第一次调用,那么CCDictionary的key类型会被确定为字符串型,之后就不能插入整型key
- //如果已存在该key,则旧key-value会被释放和移除,被新的替代
- void setObject(CCObject* pObject, const std::string& key);
- //插入一个key-value,如果是第一次调用,那么CCDictionary的key类型会被确定为整型,之后就不能插入字符串型key
- //如果已存在该key,则旧key-value会被释放和移除,被新的替代
- void setObject(CCObject* pObject, intptr_t key);
3.4.移除
- //移除指定key
- void removeObjectForKey(const std::string& key);
- void removeObjectForKey(intptr_t key);
- //移除一个CCArray中keys
- void removeObjectsForKeys(CCArray* pKeyArray);
- //通过元素来移除value
- void removeObjectForElememt(CCDictElement* pElement);
- //移除所有的key-value
- void removeAllObjects();
3.5.其他
- //返回一个随机元素,这个使用得注意,因为value可以不一样,所以返回类型每次都可能不同,在类型转换的时候要非常小心
- CCObject* randomObject();
- //返回一个包含所有key的CCArray
- CCArray* allKeys();
- //返回指定value的所有key,因为value是可以相同的,内部使用==比较两个value是否相同
- CCArray* allKeysForObject(CCObject* object);
- //返回元素个数
- unsigned int count();
- //把CCDictionary写到一个plist中,写入的value要求是字符串型
- bool writeToFile(const char *fullPath);
4.示例
- // Create a dictionary, return an autorelease object.
- CCDictionary* pDict = CCDictionary::create();
- // Insert objects to dictionary
- CCString* pValue1 = CCString::create("100");
- CCString* pValue2 = CCString::create("120");
- CCInteger* pValue3 = CCInteger::create(200);
- pDict->setObject(pValue1, "key1");
- pDict->setObject(pValue2, "key2");
- pDict->setObject(pValue3, "key3");
- // Get the object for key
- CCString* pStr1 = (CCString*)pDict->objectForKey("key1");
- CCLog("{ key1: %s }", pStr1->getCString());
- CCInteger* pInteger = (CCInteger*)pDict->objectForKey("key3");
- CCLog("{ key3: %d }", pInteger->getValue());
- CCString* pStr3=static_cast<CCString*>(pDict->randomObject());//这里有问题了,因为value有不同类型,所以随机返回时类型处理要小心
- CCLog("{ random key: %s }",pStr3->getCString()); //如果返回的是整型pValue3,那么会出现断言
- if(pDict->writeToFile("pdic.plist")) //整型的value无法写入,会提示This type cannot appear in property list
- CCLog("Write to file success!");
Resource/pdic.plist
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"/>
- <plist version="1.0">
- <dict>
- <key>key1</key>
- <string>100</string>
- <key>key2</key>
- <string>120</string>
- <key>key3</key> <!key3对应整型数据无法写入/>
- </dict>
- </plist>
5.CCDICT_FOREACH
5.1.概况
宏定义,用于遍历CCDictionary的value。
- #define CCDICT_FOREACH(__dict__, __el__) \
- CCDictElement* pTmp##__dict__##__el__ = NULL; \
- if (__dict__) \
- HASH_ITER(hh, (__dict__)->m_pElements, __el__, pTmp##__dict__##__el__)
5.2.示例
- CCDictElement* pElement;
- CCDICT_FOREACH(dict, pElement)
- {
- const char*key = pElement->getStrKey();
- // You certainly know the type of value, so we assume that it's a CCSprite.
- CCSprite* pSprite = (CCSprite*)pElement->getObject();
- // ......
- }
【玩转cocos2d-x之二十六】数据结构CCDictionary相关推荐
- 【Microsoft Azure 的1024种玩法】二十六. 在Azure VM中手动部署Windows Admin Center管理平台
[简介] Windows Admin Center是微软开发的一套可以部署在本地基于浏览器的GUI的工具集平台,其平台可用于管理Windows相关服务器和PC机器,我们可以利用Windows Admi ...
- OpenCV学习笔记(二十六)——小试SVM算法ml OpenCV学习笔记(二十七)——基于级联分类器的目标检测objdect OpenCV学习笔记(二十八)——光流法对运动目标跟踪Video Ope
OpenCV学习笔记(二十六)--小试SVM算法ml 总感觉自己停留在码农的初级阶段,要想更上一层,就得静下心来,好好研究一下算法的东西.OpenCV作为一个计算机视觉的开源库,肯定不会只停留在数字图 ...
- 计算机网络教程网线制作,图吧小白教程 篇二十六:手把手教你自制网线(夹网线水晶头)...
图吧小白教程 篇二十六:手把手教你自制网线(夹网线水晶头) 2019-11-19 23:07:38 31点赞 309收藏 27评论 创作立场声明:咕咕咕 教程最后还是出了,不过咱现在用啥还是直接网购号 ...
- (转)tensorflow入门教程(二十六)人脸识别(上)
https://blog.csdn.net/rookie_wei/article/details/81676177 1.概述 查看全文 http://www.taodudu.cc/news/show- ...
- 如何选择适合你的兴趣爱好(二十六),剪纸
如何选择适合你的兴趣爱好(二十六),剪纸 围城网的摇摇今天给大家带来了"如何选择适合你的兴趣爱好"系列专辑的第二十六讲--剪纸. 剪纸又叫刻纸,窗花或剪画,是一种用剪刀或刻刀在纸上 ...
- BetaFlight模块设计之二十六:接收机任务分析
BetaFlight模块设计之二十六:接收机任务分析 接收机任务 配置情况 硬件配置 软件配置 驱动配置 sbus驱动函数分析 sbusDataReceive函数 sbusFrameStatus函数 ...
- 2021年大数据Hadoop(二十六):YARN三大组件介绍
全网最详细的Hadoop文章系列,强烈建议收藏加关注! 后面更新文章都会列出历史文章目录,帮助大家回顾知识重点. 目录 本系列历史文章 前言 Yarn三大组件介绍 ResourceManager No ...
- 模板方法模式 Template method 行为型 设计模式(二十六)
模板方法模式 Template method 上图为网上百度的一份简历模板截图 相信大家都有求职的经历,那么必然需要简历,写简历的时候,很可能你会网上检索一份简历模板,使用此模板的格式,然后替换为你的 ...
- 窗口消息——Windows核心编程学习手札之二十六
窗口消息 --Windows核心编程学习手札之二十六 Windows允许一个进程至多建立10000个不同类型的用户对象(user object):图符.光标.窗口类.菜单.加速键表等,当一个线程调用一 ...
- 2008R2Win7管理二十六ADRMS客户端使用及侦错
2008R2Win7管理二十六ADRMS客户端使用及侦错 预计我以后都没太多时间专研新技术和写文啦,尽量挤时间吧,有一篇放一篇吧,呵呵 本篇介绍在win7客户端使用adrms来进行权限管理和侦错,在使 ...
最新文章
- MNE-Python专辑 | MNE-Python详细安装与使用(更新)
- python读取数据库之给变量_使用Python和SQLite,如何将数据库中的项读入变量?
- Java一个对象的内存运行流程图
- java面试题二十五 构造函数
- 零基础学python裴帅帅_人工智能时代,爬虫如此简单。
- 历届试题 大臣的旅费(深搜 树的直径)
- .NET 开源项目 StreamJsonRpc 介绍[上篇]
- Android插件化开发之动态加载技术系列索引
- [改善Java代码]若有必要,使用变长数组
- php cgi漏洞,Nginx + PHP CGI的一个可能的安全漏洞
- Python机器学习:逻辑回归001什么是逻辑回归
- php form 添加滚动条,element 使用总结(1. tree使用 2. table修改滚动条样式 3. el-form 自定义label添加icon)...
- (四)洞悉linux下的Netfilteriptables:包过滤子系统iptable_filter
- python中randint用法_python中的randint,引入模块
- QQ概念版酿杯具,头条下载竟是病毒
- wamp php不可用_PHPWAMP开启php
- 大数据还是人工智能?哪个发展更好
- spark.reducer.maxReqsInFlight和spark.reducer.maxBlocksInFlightPerAddress
- 【路径规划】基于粒子群算法机器人避障路径规划matlab代码
- 植物大战僵尸——最强阵容