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

#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);// CCObjectCCString时可以用这个

    

    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__ */


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值