CCDictionary基础用法

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
2
3
4
5
6
enum  CCDictType
{
     kCCDictUnknown = 0,
     kCCDictStr,
     kCCDictInt
};

2.CCDictElement

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


3.API


3.1.创建

1
2
3
4
5
6
7
8
9
//创建一个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.查找

1
2
3
4
5
6
7
8
//返回指定字符串类型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.增加

1
2
3
4
5
6
//插入一个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.移除

1
2
3
4
5
6
7
8
9
//移除指定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.其他

1
2
3
4
5
6
7
8
9
10
//返回一个随机元素,这个使用得注意,因为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.示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 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

1
2
3
4
5
6
7
8
9
10
11
12
<? 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。

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

5.2.示例

1
2
3
4
5
6
7
8
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();
     // ......
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值