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

前端之家收集整理的这篇文章主要介绍了【玩转cocos2d-x之二十六】数据结构CCDictionary前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

原创作品,转载请标明http://www.jb51.cc/article/p-azlvldlh-ep.html


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就只支持整型和字符串型了。

  1. enumCCDictType
  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.创建

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

3.2.查找

copy
    //返回指定字符串类型key的value,如果CCDictionary的key是整型,会出现断言
  1. CCObject*objectForKey(conststd::string&key);
  2. //返回指定整型key的value,如果CCDictionary的key是字符串型,会出现断言
  3. CCObject*objectForKey(intptr_tkey);
  4. //返回指定字符串类型key的CCString,这里假定value是CCString型,如果不是或者未找到,则返回空串
  5. constCCString*valueForKey(//返回指定整型类型key的CCString,这里假定value是CCString型,如果不是或者未找到,则返回空串
  6. constCCString*valueForKey(intptr_tkey);

3.3.增加

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

3.4.移除

copy
    //移除指定key
  1. voidremoveObjectForKey(voidremoveObjectForKey(intptr_tkey);
  2. //移除一个CCArray中keys
  3. voidremoveObjectsForKeys(CCArray*pKeyArray);
  4. //通过元素来移除value
  5. voidremoveObjectForElememt(CCDictElement*pElement);
  6. //移除所有的key-value
  7. voidremoveAllObjects();

3.5.其他

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

4.示例

copy
    //Createadictionary,returnanautoreleaSEObject.
  1. CCDictionary*pDict=CCDictionary::create();
  2. //Insertobjectstodictionary
  3. CCString*pValue1=CCString::create("100");
  4. CCString*pValue2=CCString::create("120");
  5. CCInteger*pValue3=CCInteger::create(200);
  6. pDict->setObject(pValue1,"key1");
  7. pDict->setObject(pValue2,"key2");
  8. pDict->setObject(pValue3,"key3");
  9. //Gettheobjectforkey
  10. CCString*pStr1=(CCString*)pDict->objectForKey("key1");
  11. CCLog("{key1:%s}",pStr1->getCString());
  12. CCInteger*pInteger=(CCInteger*)pDict->objectForKey("key3");
  13. CCLog("{key3:%d}",pInteger->getValue());
  14. CCString*pStr3=static_cast<CCString*>(pDict->randomObject());//这里有问题了,因为value有不同类型,所以随机返回时类型处理要小心
  15. CCLog("{randomkey:%s}",pStr3->getCString());//如果返回的是整型pValue3,那么会出现断言
  16. if(pDict->writeToFile("pdic.plist"))//整型的value无法写入,会提示Thistypecannotappearinpropertylist
  17. CCLog("Writetofilesuccess!");
Resource/pdic.plist

[html] copy
    <?xmlversion="1.0"encoding="UTF-8"?>
  1. <!DOCTYPEplistPUBLIC"-//Apple//DTDPLIST1.0//EN""http://www.apple.com/DTDs/PropertyList-1.0.dtd"/>
  2. <plistversion="1.0">
  3. dict>
  4. key>key1</string>100>key2>120>key3><!key3对应整型数据无法写入plist>

5.CCDICT_FOREACH


5.1.概况

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

copy
    #defineCCDICT_FOREACH(__dict__,__el__)\
  1. CCDictElement*pTmp##__dict__##__el__=NULL;\
  2. if(__dict__)\
  3. HASH_ITER(hh,(__dict__)->m_pElements,__el__,pTmp##__dict__##__el__)

5.2.示例

copy
    CCDictElement*pElement;
  1. CCDICT_FOREACH(dict,pElement)
  2. {
  3. char*key=pElement->getStrKey();
  4. //Youcertainlyknowthetypeofvalue,soweassumethatit'saCCSprite.
  5. CCSprite*pSprite=(CCSprite*)pElement->getObject();
  6. //......
  7. }
原文链接:https://www.f2er.com/cocos2dx/342132.html

猜你在找的Cocos2d-x相关文章