您的位置:首页 > 移动开发 > Objective-C

CCDictionary(封装了哈希表.可以加入两种元素:键为整型或字符串值为ccobject.CCDICT_FOREACH objectForKey allKeysForObject setObj)

2014-05-23 10:29 579 查看
#ifndef __CCDICTIONARY_H__
#define __CCDICTIONARY_H__

#include "support/data_support/uthash.h"
#include "CCObject.h"
#include "CCArray.h"
#include "CCString.h"

NS_CC_BEGIN

class CCDictionary;

/**
* CCDictElement is used for traversing(遍历) CCDictionary.
*
* A CCDictElement is one element of CCDictionary, it contains two properties, key and object. //字典元素是字典一个元素 它包含2个属性
键 和 值
* Its key has two different type (integer and string). //键有两个不同类型 整型和字符串
*
* @note The key type is unique(唯一的), all the elements in CCDictionary has the same key type(integer or string).

* 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();
* // ......
* }
*
*/
class CC_DLL CCDictElement //字典元素
{
private:
//字典元素构造函数 两种方式 1、键值为字符串 2、键值为整型 两种方式键对应的值都是CCObject。
CCDictionary is its friend class.
CCDictElement(const char* pszKey, CCObject* pObject);

CCDictElement(intptr_t iKey, CCObject* pObject);

public:
~CCDictElement();

// Inline functions need to be implemented(实行) in header file on Android.

inline const char* getStrKey() const
//像这种简单的函数 设置为内联函数。 编译时直接文本替换(类似宏 因为函数简单可以这样处理) 节省了调用函数时的时间开销
{
CCAssert(m_szKey[0] != '\0', "Should not call this function for integer dictionary");
return m_szKey;
}

inline intptr_t getIntKey() const
{
CCAssert(m_szKey[0] == '\0', "Should not call this function for string dictionary");
return m_iKey;
}

inline CCObject*
getObject() const { return m_pObject; }

private:
#define MAX_KEY_LEN 256 //定义字符串key最大长度 不一定非要在文件开头定义
// char array is needed for HASH_ADD_STR in UT_HASH.

// So it's a pain that all elements will allocate 256 bytes for this array.
char m_szKey[MAX_KEY_LEN]; // hash key of string type
intptr_t m_iKey; // hash key of integer type
CCObject* m_pObject; // hash value
public:
UT_hash_handle hh; // makes this class hash able 句柄

////////////
int类型key

  总结int类型key使用方法,可以看到其查找和插入分别使用专用接口:HASH_FIND_INT和ASH_ADD_INT。

  4.2. 字符指针char*类型key与字符数组char key[100]类型key

  特别注意在Strting类型中,uthash对指针char*和字符数组(例如char key[100])做了区分,这两种情况下使用的接口函数时不一样的。在添加的时候,key的类型为指针时使用接口函数HASH_ADD_KEYPTR,key的类型为字符数组时,使用接口函数HASH_ADD_STR,除了添加的接口不一样外,其他的查找、删除、变量等接口函数都是一样的。
/////////

friend class CCDictionary; // declare(声明) CCDictionary as friend class
};

/** The macro for traversing(遍历) dictionary
*
* @note It's faster than getting all keys and traversing keys to get objects by objectForKey.
* It's also safe to remove elements while traversing.
*/
#define CCDICT_FOREACH(__dict__, __el__) \
//遍历字典 允许遍历时删除元素
CCDictElement* pTmp##__dict__##__el__ = NULL; \
if (__dict__) \
HASH_ITER(hh, (__dict__)->m_pElements, __el__, pTmp##__dict__##__el__)

/**
* Only the pointer of CCObject or its subclass can be inserted to CCDictionary.//仅object或其子类的 指针允许插入字典作为值
* // 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());
* @endcode
*
*/

class CC_DLL CCDictionary : public CCObject //内部通过哈希表实现
{
public:
CCDictionary();

~CCDictionary();

unsigned int
count();

{
return HASH_COUNT(m_pElements);
}
/**
* Return all keys of elements.
*/
CCArray*
allKeys();// 返回所有字典元素的 键数组

/**
* Get all keys according to the specified object.
* @warning We use '==' to compare two objects
*/
CCArray*
allKeysForObject(CCObject* object);//得到所有对应参数值的 键数组

CCObject*
objectForKey(const std::string& key); //通过键 得到值

CCObject*
objectForKey(intptr_t key);

/** Get the value according to the specified string key.
*
* @note Be careful to use this function since it assumes(假设) the objects in the dictionary are CCString pointer.
* @param key The string key for searching
* @return An instance of CCString.
* It will return an empty string if the objects aren't CCString pointer or the key wasn't found.
* @see valueForKey(intptr_t)
*/
const CCString* valueForKey(const std::string& key);//
CCObject 是CCString时可以用这个

const CCString* valueForKey(intptr_t key);

void
setObject(CCObject* pObject, const std::string& key); //插入元素

void
setObject(CCObject* pObject, intptr_t key);//插入元素

void
removeObjectForKey(const std::string& key); //删除对应给定键的ccobjet

void
removeObjectForKey(intptr_t key);//删除对应给定键的ccobjet

void
removeObjectsForKeys(CCArray* pKeyArray);
//删除对应给定键数组的所有ccobjets

void
removeObjectForElememt(CCDictElement* pElement);
//直接删除一个给定元素

void
removeAllObjects();

/// @{
/// @name Function override
/**
* This function is used for deepcopy elements from source dictionary to destination dictionary.
* You shouldn't invoke this function manually since it's called by CCObject::copy.
*/
virtual CCObject* copyWithZone(CCZone* pZone);
/// @}

CCObject*
randomObject(); //随机得到字典里一个元素

static CCDictionary*
create();
//创建字典 空得

static CCDictionary*
createWithDictionary(CCDictionary* srcDict); //使用已有字典 创建字典

static CCDictionary*
createWithContentsOfFile(const char *pFileName);
//使用plist文件创建一个字典

/**
* Write a dictionary to a plist file.
* @param fullPath The full path of the plist file. You can get writeable path by getWritablePath()
*/
bool
writeToFile(const char *fullPath);
//把字典数据写入一个plist文件

/**
* Create a dictionary with a plist file.
*
* @note the return object
isn't an autorelease object.
* This can make sure not using autorelease pool in a new thread.
* Therefore, you need to manage the lifecycle of the return object.
* It means that when you don't need it, CC_SAFE_RELEASE needs to be invoked.
*
* @param pFileName The name of the plist file.
* @return A dictionary which isn't an autorelease object.
*/
static CCDictionary*
createWithContentsOfFileThreadSafe(const char *pFileName);
///,,,,,,,,,,,,,,

/* override functions */
virtual void
acceptVisitor(CCDataVisitor &visitor); //????????

private:
/**
* For internal usage, invoked by setObject.
*/
//内部函数 被setObject调用
void setObjectUnSafe(CCObject* pObject, const std::string& key);
void setObjectUnSafe(CCObject* pObject, const intptr_t key);

public:
/**
* All the elements in dictionary.
*
* @note For internal usage, we need to declare this member variable as public since it's used in UT_HASH.
*/
CCDictElement* m_pElements; //是公有的!!!!!!
private:

/** The support type of dictionary, it's confirmed when setObject is invoked. */
enum
CCDictType
{
kCCDictUnknown = 0,
kCCDictStr,
kCCDictInt
};

/**
* The type of dictionary, it's assigned to kCCDictUnknown by default.
*/
CCDictType m_eDictType;
};

NS_CC_END

#endif /* __CCDICTIONARY_H__ */
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: