CCDictionary(转)
#ifndef __CCDICTIONARY_H__
#define __CCDICTIONARY_H__
//需要哈希表的支持
#include "support/data_support/uthash.h"
#include "CCObject.h"
#include "CCArray.h"
#include "CCString.h"
//Cocos2d命名空间
NS_CC_BEGIN
//声明一下CCDictionary类,因为CCDictElement要用到CCDictionary指针。
class CCDictionary; //词典元素,或者简单理解就是词典中的一个词汇。我们从小查词典都知道,通过词汇名称或索引查找到对应的解释。解释与词汇名称或索引之间是一一对应的关系。与这种关系相同,在这个词汇类中存储一个字符串名称或一个索引以及与其相应的CCObject指针,这个CCObject指针就相当于是我们查出来的解释一样与字符串名称或索引构成了对应关系。 class CC_DLL CCDictElement
{
//定义字符串名称的长度.
#define MAX_KEY_LEN 256
public:
//构造函数。
//参1:字符串名称。
//参2:对应的CCObject指针。
CCDictElement(const char* pszKey, CCObject* pObject)
{
//初始化。
init();
m_pObject = pObject;
//
const char* pStart = pszKey;
//字符串的字节长度
int len = strlen(pszKey);
if (len > MAX_KEY_LEN )
{ //如果长度大于MAX_KEY_LEN,截取后面MAX_KEY_LEN长度字符串。
char* pEnd = (char*)&pszKey[len-];
pStart = pEnd - (MAX_KEY_LEN-);
}
//字符串COPY
strcpy(m_szKey, pStart);
}
//构造函数
//参1:所在哈希表中的索引
//参2:对应的CCObject指针。
CCDictElement(int iKey, CCObject* pObject)
{
init();
m_iKey = iKey;
m_pObject = pObject;
}
//取得名称字符串。
inline const char* getStrKey() const
{
CCAssert(m_szKey[] != '\0', "Should not call this function for integer dictionary");
return m_szKey;
}
//取得哈希索引。
inline int getIntKey() const
{
CCAssert(m_szKey[] == '\0', "Should not call this function for string dictionary");
return m_iKey;
}
//取得CCObject指针。
inline CCObject* getObject() const
{
return m_pObject;
} private:
//初始化。
inline void init()
{
m_iKey = ;
m_pObject = NULL;
memset(m_szKey, , sizeof(m_szKey));
memset(&hh, , sizeof(hh));
} private:
char m_szKey[MAX_KEY_LEN+]; //存储名称的字符数组。
int m_iKey; //哈希表索引
CCObject* m_pObject; //哈希值(CCObject指针)
public:
UT_hash_handle hh; //哈希表结构指针
friend class CCDictionary; //词典为友元类
}; //遍历词典中的所有词汇的一个宏,它内部调用HASH_ITER来进行for循环遍历链表。
#define CCDICT_FOREACH(__dict__, __el__) \
CCDictElement* pTmp##__dict__##__el__ = NULL; \
HASH_ITER(hh, (__dict__)->m_pElements, __el__, pTmp##__dict__##__el__) //词典类,由CCObject派生
class CC_DLL CCDictionary : public CCObject
{
public:
//构造函数
CCDictionary();
//析构函数
~CCDictionary(); //取得所有词汇的数量。
unsigned int count(); //返回所有的查询关键字。
CCArray* allKeys(); //取得对应CCObject指针的所有关键字或索引值。
CCArray* allKeysForObject(CCObject* object);
//通过查询关键字取得对应CCObject指针
CCObject* objectForKey(const std::string& key);
//通过哈希索引值取得对应CCObject指针
CCObject* objectForKey(int key);
//通过查询关键字取得对应CCString指针
const CCString* valueForKey(const std::string& key);
//通过哈希索引值取得对应CCString指针
const CCString* valueForKey(int key);
//设置一个CCObject和对应的名称存入词典。
void setObject(CCObject* pObject, const std::string& key);
//设置一个CCObject和对应的哈希索引存入词典。
void setObject(CCObject* pObject, int key);
//按照查询关键字找到对应CCObject并删除。
void removeObjectForKey(const std::string& key);
//按照哈希索引找到对应CCObject并删除。
void removeObjectForKey(int key);
//按照容器中的查询关键字找到对应CCObject并删除。
void removeObjectsForKeys(CCArray* pKeyArray);
//从词典中删除相应的词汇。
void removeObjectForElememt(CCDictElement* pElement);
//从词典中清空所有的词汇。
void removeAllObjects();
//重载CCObject的拷贝函数。产生一个一模一样的词典。
virtual CCObject* copyWithZone(CCZone* pZone); //静态函数,取得单例的词典。请改用create函数,因为这个函数以后将被删除掉。
CC_DEPRECATED_ATTRIBUTE static CCDictionary* dictionary(); //静态函数,取得一个指定词典的COPY,请改用createWithDictionary函数,因为这个函数以后将被删除掉。
CC_DEPRECATED_ATTRIBUTE static CCDictionary* dictionaryWithDictionary(CCDictionary* srcDict); //静态函数:从一个plist文件中加载词典内容。此函数创建的词典是交由内存管理器来进行资源计数的,不需手动release。但请改用createWithContentsOfFile函数,因为这个函数以后也将被删除掉。
CC_DEPRECATED_ATTRIBUTE static CCDictionary* dictionaryWithContentsOfFile(const char *pFileName); //静态函数:从一个plist文件中加载词典内容,但此函数是多线程安全的,另外此函数创建的词典需要手动release。请改用 createWithContentsOfFileThreadSafe函数,因为这个函数以后也将被删除掉。
CC_DEPRECATED_ATTRIBUTE static CCDictionary* dictionaryWithContentsOfFileThreadSafe(const char *pFileName);
//静态函数,创建一个新词典
static CCDictionary* create();
//静态函数,取得一个指定词典的COPY。
static CCDictionary* createWithDictionary(CCDictionary* srcDict); //静态函数:从一个plist文件中加载词典内容。
static CCDictionary* createWithContentsOfFile(const char *pFileName);
//静态函数:从一个plist文件中加载词典内容,但此函数是多线程安全的,另外此函数创建的词典需要手动release。
static CCDictionary* createWithContentsOfFileThreadSafe(const char *pFileName); private:
//将CCObject实例指针与对应的字符串名称存入哈希表。
void setObjectUnSafe(CCObject* pObject, const std::string& key);
//将CCObject实例指针与对应的索引值存入哈希表。
void setObjectUnSafe(CCObject* pObject, const int key); public:
//词汇的哈希表头部结构指针。
CCDictElement* m_pElements;
private:
//词典查询类型。
enum CCDictType
{
kCCDictUnknown = ,
kCCDictStr,//字符串名称
kCCDictInt //索引
};
CCDictType m_eDictType; //当前词典查询类型。一个词典实例要求只有一种固定词典查询类型。
CCDictType m_eOldDictType; //上次词典查询类型。这个变量是用来比对是否改变了词典查询类型。
};
NS_CC_END
#include "CCDictionary.h"
#include "CCString.h"
#include "CCInteger.h"
using namespace std;
//使用Cocos2d命名空间
NS_CC_BEGIN
//构造函数
CCDictionary::CCDictionary()
: m_pElements(NULL)
, m_eDictType(kCCDictUnknown)
, m_eOldDictType(kCCDictUnknown)
{ }
//析构函数。
CCDictionary::~CCDictionary()
{
//请空词汇,释放所有词汇占用的内存。
removeAllObjects();
}
//取得词典中的所有词汇数量。
unsigned int CCDictionary::count()
{
//通过HASH_CONT宏来取得哈希表的元素数量。
return HASH_COUNT(m_pElements);
}
//返回所有的查询关键字。
CCArray* CCDictionary::allKeys()
{
//取得词汇的数量
int iKeyCount = this->count();
if (iKeyCount <= ) return NULL;
//创建一个iKeyCount大小的CCArray
CCArray* pArray = CCArray::createWithCapacity(iKeyCount);
//定义临时词汇指针变量。
CCDictElement *pElement, *tmp;
if (m_eDictType == kCCDictStr)
{ //如果当前词典查询类型是通过名称字符串。
//遍历所有词汇。
HASH_ITER(hh, m_pElements, pElement, tmp)
{
//取得每一个词汇的名称字符串放入CCArray中。
CCString* pOneKey = new CCString(pElement->m_szKey);
pOneKey->autorelease();
pArray->addObject(pOneKey);
}
}
else if (m_eDictType == kCCDictInt)
{ //如果当前词典查询类型是通过索引。
//遍历所有词汇。 HASH_ITER(hh, m_pElements, pElement, tmp)
{
//取得每一个词汇的名称字符串放入CCArray中。
CCInteger* pOneKey = new CCInteger(pElement->m_iKey);
pOneKey->autorelease();
pArray->addObject(pOneKey);
}
} return pArray;
}
//取得对应CCObject指针的所有关键字或索引值。
CCArray* CCDictionary::allKeysForObject(CCObject* object)
{
//取得词汇的数量
int iKeyCount = this->count();
if (iKeyCount <= ) return NULL;
//创建一个CCArray。
CCArray* pArray = CCArray::create();
//定义临时词汇指针变量。
CCDictElement *pElement, *tmp;
if (m_eDictType == kCCDictStr)
{ //如果当前词典查询类型是通过名称字符串。
//遍历所有词汇。
HASH_ITER(hh, m_pElements, pElement, tmp)
{
if (object == pElement->m_pObject)
{
//如果与指定的词汇相同,将其名称字符串放入CCArray中。
CCString* pOneKey = new CCString(pElement->m_szKey);
pArray->addObject(pOneKey);
pOneKey->release();
}
}
}
else if (m_eDictType == kCCDictInt)
{ //如果当前词典查询类型是通过索引。
//遍历所有词汇。
HASH_ITER(hh, m_pElements, pElement, tmp)
{
//如果与指定的词汇相同,将其名称字符串放入CCArray中。
if (object == pElement->m_pObject)
{
CCInteger* pOneKey = new CCInteger(pElement->m_iKey);
pArray->addObject(pOneKey);
pOneKey->release();
}
}
}
return pArray;
}
//通过查询关键字取得对应CCObject指针
CCObject* CCDictionary::objectForKey(const std::string& key)
{
//当前词典查询类型值有效性判断。此处有错,应该改为:if (m_eDictType == kCCDictUnknown || m_eDictType == kCCDictInt) return NULL;
if (m_eDictType == kCCDictUnknown && m_eDictType == kCCDictUnknown) return NULL;
//要求当前词典查询类型为按字符串查询。
CCAssert(m_eDictType == kCCDictStr, "this dictionary does not use string as key.");
//定义临时词汇指针变量。
CCObject* pRetObject = NULL;
CCDictElement *pElement = NULL;
//通过名称字符串查询哈希表中的相应词汇
HASH_FIND_STR(m_pElements, key.c_str(), pElement);
if (pElement != NULL)
{
//如果查询到词汇,返回其对应的CCObject指针
pRetObject = pElement->m_pObject;
}
return pRetObject;
}
//通过查询索引取得对应CCObject指针
CCObject* CCDictionary::objectForKey(int key)
{
//当前词典查询类型值有效性判。此处有错,应该改为:if (m_eDictType == kCCDictUnknown || m_eDictType == kCCDictStr) return NULL;
if (m_eDictType == kCCDictUnknown && m_eDictType == kCCDictUnknown) return NULL;
//要求当前词典查询类型为按字符串查询。
CCAssert(m_eDictType == kCCDictInt, "this dictionary does not use integer as key.");
//定义临时词汇指针变量。
CCObject* pRetObject = NULL;
CCDictElement *pElement = NULL;
//通过索引查询哈希表中的相应词汇
HASH_FIND_INT(m_pElements, &key, pElement);
if (pElement != NULL)
{
//如果查询到词汇,返回其对应的CCObject指针
pRetObject = pElement->m_pObject;
}
return pRetObject;
}
//通过查询关键字取得对应CCString指针,其实即要求存入词汇的CCObject指针是CCString实例对象指针。
const CCString* CCDictionary::valueForKey(const std::string& key)
{
//将通过查询关键字取得对应CCString指针强转为CCString指针。
CCString* pStr = (CCString*)objectForKey(key);
if (pStr == NULL)
{
//如果没找到,返回空字符串
pStr = CCString::create("");
}
return pStr;
}
//通过查询索引取得对应CCString指针,即要求存入词汇的CCObject指针是CCString实例对象指针。
const CCString* CCDictionary::valueForKey(int key)
{
//将通过查询索引取得对应CCString指针强转为CCString指针。
CCString* pStr = (CCString*)objectForKey(key);
if (pStr == NULL)
{
//如果没找到,返回空字符串
pStr = CCString::create("");
}
return pStr;
}
//设置一个CCObject和对应的名称存入词典。
void CCDictionary::setObject(CCObject* pObject, const std::string& key)
{
//参数有效性判断
CCAssert(key.length() > && pObject != NULL, "Invalid Argument!");
//如果是第一次存入,记录查询类型为字符串类型。
if (m_eOldDictType == kCCDictUnknown)
{
m_eOldDictType = kCCDictStr;
}
//将当前词典查询类型设为字符串查询类型。这个变量是可以省略的,因为要求词典查询类型为固定。只用m_eOldDictType就可以了。
m_eDictType = kCCDictStr;
CCAssert(m_eDictType == m_eOldDictType, "this dictionary does not use string as key.");
//定义临时指针变量从词典中取得对应名称的词汇。
CCDictElement *pElement = NULL;
HASH_FIND_STR(m_pElements, key.c_str(), pElement);
if (pElement == NULL)
{
//如果词典中没有此词汇,将此新词汇放入词典。
setObjectUnSafe(pObject, key);
}
else if (pElement->m_pObject != pObject)
{
//如果词典中已有此词汇,则删除老词汇放入新词汇。
CCObject* pTmpObj = pElement->m_pObject;
//此处调用retain对引用计数器加1可以避免在后面的删除函数中释放pTmpObj指向的CCObject。
pTmpObj->retain();
//删除此词汇
removeObjectForElememt(pElement);
//放入新词汇。
setObjectUnSafe(pObject, key);
//因为之前retain对引用计数器加1一次,所以必须release对引用计数器减1一次才能保证由内存管理器来进行内存释放时,pTempObj指向的CCObject可以正确的被释放掉。
pTmpObj->release();
}
} //设置一个CCObject和对应的哈希索引存入词典。
void CCDictionary::setObject(CCObject* pObject, int key)
{
//参数有效性判断
CCAssert(pObject != NULL, "Invalid Argument!");
//如果是第一次存入,记录查询类型为索引类型。
if (m_eOldDictType == kCCDictUnknown)
{
m_eOldDictType = kCCDictInt;
}
//将当前词典查询类型设为索引查询类型。这个变量是可以省略的,因为要求词典查询类型为固定。只用m_eOldDictType就可以了。
m_eDictType = kCCDictInt;
//一致性判断
CCAssert(m_eDictType == m_eOldDictType, "this dictionary does not use integer as key.");
//定义临时指针变量从词典中取得对应名称的词汇。
CCDictElement *pElement = NULL;
HASH_FIND_INT(m_pElements, &key, pElement);
if (pElement == NULL)
{
//如果词典中没有此词汇,将此新词汇放入词典。
setObjectUnSafe(pObject, key);
}
else if (pElement->m_pObject != pObject)
{
//如果词典中已有此词汇,则删除老词汇放入新词汇。
CCObject* pTmpObj = pElement->m_pObject;
//此处调用retain对引用计数器加1可以避免在后面的删除函数中释放pTmpObj指向的CCObject。
pTmpObj->retain();
//删除此词汇
removeObjectForElememt(pElement);
//放入新词汇。
setObjectUnSafe(pObject, key);
//因为之前retain对引用计数器加1一次,所以必须release对引用计数器减1一次才能保证由内存管理器来进行内存释放时,pTempObj指向的CCObject可以正确的被释放掉。
pTmpObj->release();
} }
//按照查询关键字找到对应CCObject并删除。
void CCDictionary::removeObjectForKey(const std::string& key)
{
//当前词典是否有效
if (m_eOldDictType == kCCDictUnknown)
{
return;
}
//当前词典的查询类型是否为字符串名称查询方式
CCAssert(m_eDictType == kCCDictStr, "this dictionary does not use string as its key");
//参数有效性判断
CCAssert(key.length() > , "Invalid Argument!");
//定义临时指针变量从词典中取得对应名称的词汇。
CCDictElement *pElement = NULL;
HASH_FIND_STR(m_pElements, key.c_str(), pElement);
//从词典中删除相应的词汇。
removeObjectForElememt(pElement);
} void CCDictionary::removeObjectForKey(int key)
{
//当前词典是否有效
if (m_eOldDictType == kCCDictUnknown)
{
return;
}
//当前词典的查询类型是否为索引查询方式
CCAssert(m_eDictType == kCCDictInt, "this dictionary does not use integer as its key");
//定义临时指针变量从词典中取得对应索引的词汇。
CCDictElement *pElement = NULL;
HASH_FIND_INT(m_pElements, &key, pElement);
//从词典中删除相应的词汇。
removeObjectForElememt(pElement);
}
//将CCObject实例指针与对应的字符串名称存入哈希表。
void CCDictionary::setObjectUnSafe(CCObject* pObject, const std::string& key)
{
//对pObject指向的实例对像引用计数器加1,即告诉其被词典使用.避免万一其的其它使用者都不再使用时被内存管理器释放.
pObject->retain();
//由pObject和名称字符串产生一个新的词汇。
CCDictElement* pElement = new CCDictElement(key.c_str(), pObject);
//将新的词汇放入哈希表中。
HASH_ADD_STR(m_pElements, m_szKey, pElement);
}
//将CCObject实例指针与对应的索引存入哈希表。
void CCDictionary::setObjectUnSafe(CCObject* pObject, const int key)
{
//对pObject指向的实例对像引用计数器加1,即告诉其被词典使用.避免万一其的其它使用者都不再使用时被内存管理器释放.
pObject->retain();
//由pObject和名称字符串产生一个新的词汇。
CCDictElement* pElement = new CCDictElement(key, pObject);
//将新的词汇放入哈希表中。
HASH_ADD_INT(m_pElements, m_iKey, pElement);
} //按照容器中的查询关键字找到对应CCObject并删除。
void CCDictionary::removeObjectsForKeys(CCArray* pKeyArray)
{
//遍历CCArray实例对像的所有名称字符串,查询与之对应的词汇。并删除。
CCObject* pObj = NULL;
CCARRAY_FOREACH(pKeyArray, pObj)
{
CCString* pStr = (CCString*)pObj;
removeObjectForKey(pStr->getCString());
}
}
//从词典中删除相应的词汇。
void CCDictionary::removeObjectForElememt(CCDictElement* pElement)
{
//参数有效性判断
if (pElement != NULL)
{
//从哈希表中删除pElement指向的词汇
HASH_DEL(m_pElements, pElement);
//前面在将词汇加入词典时对引用计数器加1,这里删除词汇是就应该对引用计数器减1。
pElement->m_pObject->release();
//释放词汇
CC_SAFE_DELETE(pElement);
}
}
//从词典中清空所有的词汇。
void CCDictionary::removeAllObjects()
{
//定义遍历哈希表所用的指针变量
CCDictElement *pElement, *tmp;
//遍历哈希表
HASH_ITER(hh, m_pElements, pElement, tmp)
{
//删除词汇并释放
HASH_DEL(m_pElements, pElement);
pElement->m_pObject->release();
CC_SAFE_DELETE(pElement);
}
}
//重载CCObject的拷贝函数。产生一个一模一样的词典。
CCObject* CCDictionary::copyWithZone(CCZone* pZone)
{
//参数有效性判断
CCAssert(pZone == NULL, "CCDirctionary should not be inherited.");
//创建一个新的词典
CCDictionary* pNewDict = new CCDictionary();
//定义用来遍历的临时变量
CCDictElement* pElement = NULL;
CCObject* pTmpObj = NULL;
//如果是索引查询方式
if (m_eDictType == kCCDictInt)
{
//遍历所有词汇
CCDICT_FOREACH(this, pElement)
{
//产生遍历词汇对应的CCObject的COPY,生成新的词汇放入新的词典中.
pTmpObj = pElement->getObject()->copy();
pNewDict->setObject(pTmpObj, pElement->getIntKey());
pTmpObj->release();
}
}
else if (m_eDictType == kCCDictStr)
{
//如果是名称字符串查询方式.
//遍历所有词汇
CCDICT_FOREACH(this, pElement)
{
//产生遍历词汇对应的CCObject的COPY,生成新的词汇放入新的词典中.
pTmpObj = pElement->getObject()->copy();
pNewDict->setObject(pTmpObj, pElement->getStrKey());
pTmpObj->release();
}
} return pNewDict;
}
//静态函数,取得单例的词典,内部调用create函数。
CCDictionary* CCDictionary::dictionary()
{
return CCDictionary::create();
}
//静态函数,取得单例的词典。
CCDictionary* CCDictionary::create()
{
//创建一个新的词典
CCDictionary* pRet = new CCDictionary();
if (pRet != NULL)
{
//将其设为由引用计数器来判断释放时机.交由内存管理器进行管理.
pRet->autorelease();
}
//返回新创建的词典指针
return pRet;
}
//静态函数,取得一个指定词典的COPY,内部调用createWithDictionary函数.
CCDictionary* CCDictionary::dictionaryWithDictionary(CCDictionary* srcDict)
{
return CCDictionary::createWithDictionary(srcDict);
}
//静态函数,取得一个指定词典的COPY.
CCDictionary* CCDictionary::createWithDictionary(CCDictionary* srcDict)
{
//查生一个指定词典的COPY.
CCDictionary* pNewDict = (CCDictionary*)srcDict->copy();
pNewDict->autorelease();
return pNewDict;
} //声明静态函数:从一个plist文件中加载词典内容,此函数是多线程安全的,其内部调用 createWithContentsOfFileThreadSafe函数。
extern CCDictionary* ccFileUtils_dictionaryWithContentsOfFileThreadSafe(const char *pFileName); //静态函数:从一个plist文件中加载词典内容,此函数是多线程安全的.
CCDictionary* CCDictionary::dictionaryWithContentsOfFileThreadSafe(const char *pFileName)
{
return CCDictionary::createWithContentsOfFileThreadSafe(pFileName);
}
//静态函数:从一个plist文件中加载词典内容,此函数是多线程安全的.
CCDictionary* CCDictionary::createWithContentsOfFileThreadSafe(const char *pFileName)
{
//这里调用Cocos2d-x的文件函数集中的带多线程安全的从plist文件加载词典函数实现相应功能.
return ccFileUtils_dictionaryWithContentsOfFileThreadSafe(pFileName);
} //静态函数:从一个plist文件中加载词典内容,其内部调用 createWithContentsOfFile函数。
CCDictionary* CCDictionary::dictionaryWithContentsOfFile(const char *pFileName)
{
return CCDictionary::createWithContentsOfFile(pFileName);
}
//静态函数:从一个plist文件中加载词典内容.
CCDictionary* CCDictionary::createWithContentsOfFile(const char *pFileName)
{
CCDictionary* pRet = createWithContentsOfFileThreadSafe(pFileName);
pRet->autorelease();
return pRet;
} NS_CC_END
CCDictionary(转)的更多相关文章
- cocos2d CCDictionary
CCDictionary* dict=CCDictionary::create(); CCString* str1=CCString::create("); CCString* str2=C ...
- CCDictionary&CCArray执行retain()重要点
CCDictionary也需要执行retain(),否则则跟CCArray,返回则释放对象. 在Lua中,忘记了retain(),导致一些出现gCCDictionary:objectForKey(ke ...
- 7.数据本地化CCString,CCArray,CCDictionary,tinyxml2,写入UserDefault.xml文件,操作xml,解析xml
数据本地化 A CCUserDefault 系统会在默认路径cocos2d-x-2.2.3\projects\Hello\proj.win32\Debug.win32下生成一个名为UserDef ...
- CCDictionary
/** * CCDictionary is a class like NSDictionary in Obj-C . * * @note Only the pointer of CCObject or ...
- cocos2d-x3.0 用CCDictionary写文件
bool CDownLoad_LocalData::WriteToConfigFile( DownLoadLocalData* downdata ){ CCDictionary* pDict = CC ...
- CCDictionary 用调试器查看问题
if(dic->objectForKey("uid")) uid = dic->valueForKey("uid")->getCString( ...
- !cocos2d ccdictionary->retain()的问题
我再a类当中生命了一个dict,将它带入到b类当中,但没有在b类初始化时retain,于是在update当中找不到了.啃爹不.记得retain()
- 【Cocos2d-x for WP8 学习整理】(5)文字显示全整理
学习 Cocos2d-x 有一阵了,现在要做个小东西,第一步就遇到了文字展示的问题,于是想把可能遇到的问题统统整理一下.这一部分也不局限于wp8,全平台应该都是一个解决方案. 先在脑袋里大致想了一下, ...
- [原创]cocos2d-x研习录-第三阶 特性之瓦片地图集
由于一张大的世界地图或背景图片往往可以由屈指可数的几种地形来表示,每种地形对应于一张小的图片,我们称这些小的地形图片为瓦片.把这些瓦片拼接在一起,组合成一个完整的地图,这就是瓦片地图集的基本原理. C ...
随机推荐
- UIKeyboardTypeNumberPad 数字键盘添加完成按钮
一:添加通知 //数字键盘添加完成 [[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(keyboardWi ...
- 算法笔记_109:第四届蓝桥杯软件类省赛真题(JAVA软件开发本科B组部分习题)试题解答
目录 1 马虎的算式 2 黄金连分数 3 有理数类 4 幸运数 5 连号区间数 前言:以下试题解答代码部分仅供参考,若有不当之处,还请路过的同学提醒一下~ 1 马虎的算式 标题: 马虎的算式 小明 ...
- URI是什么意思?URI和URL有什么区别?
URI是什么意思?URI和URL有什么区别? 详解! HTTP = Hyper Text Transfer ProtocolURI = Universal Resource IdentifierURL ...
- ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER privilege(s) for this operation
开启super权限: 1. update user set Super_priv=‘Y’ where User=‘root’2. flush privileges
- 【安卓】给gallery内"控件"挂载事件,滑动后抬起手指时也触发事件(滑动时不应触发)的解决、!
思路: 1.gallery内控件挂载事件(如:onClickListener)的方法类似listview,可直接在baseAdapter.getView内给控件挂载(详细方法百度). 2.貌似没问题, ...
- 引入css的几种方式
使用CSS样式的几种方式 CreateTime--2017年10月11日16:45:26 Author:Marydon a.外部样式 a1.链接式(推荐使用) <link href=&quo ...
- C语言第一个例子hello world
1.用文本编辑器编辑代码如下,然后保存为hello.c文件 #include <stdio.h> int main(void){ printf("hello world" ...
- Git恢复之前版本的两种方法reset、revert(图文详解)
一.问题描述在利用github实现多人合作程序开发的过程中,我们有时会出现错误提交的情况,此时我们希望能撤销提交操作,让程序回到提交前的样子,本文总结了两种解决方法:回退(reset).反做(reve ...
- web.config配置数据库连接(转)
摘自:http://www.cnblogs.com/breezeblew/archive/2008/05/01/1178719.html 第一种: 取连接字符串 string connString = ...
- 狄斯奎诺(dijkstra 模板)
/*狄斯奎诺算法(dijkstra)<邻接表> */ #include<stdio.h> #include<string.h> #include<stdlib ...