[cocos2dx笔记016]cocos2dx 3.2 的UserDefault

前端之家收集整理的这篇文章主要介绍了[cocos2dx笔记016]cocos2dx 3.2 的UserDefault前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
本文地址:http://www.cppblog.com/zdhsoft/archive/2014/09/03/208216.html
本文基于cocos2dx 3.2
cocos2dx 提供了一个基于xml的用户数据存贮类,给基于cocos2dx开发的用户数据存贮,这个类名就是UserDefault,在cocos2dx 2.x中是CCUserDefault。我的程序用的就是这个,但是最近老出错,于是分析源代码,发现了一个让我震惊的东西。经过分析,发现用UserDefault每读写一次数据,都会创建一个tinyxml对象,然后读取xml内容。如果是写数据,还是写入xml一次。下面是对应的代码
读取key,所以各种读取key的操作,都是类似这样。
doubleUserDefault::getDoubleForKey( const char*pKey,doubledefaultValue)
{
char*value=nullptr;
tinyxml2::XMLElement*rootNode;
tinyxml2::XMLDocument*doc;
tinyxml2::XMLElement*node;
node=getXMLNodeForKey(pKey,&rootNode,&doc);
// findthenode
if(node&&node->FirstChild())
{
value=( char*)(node->FirstChild()->Value());
}

doubleret=defaultValue;

if(value)
{
ret=utils::atof(value);
}

if(doc)deletedoc;

returnret;
}
关于getXMLNodeForKey的实现
/* *
*definethefunctionsherebecausewedon'twantto
*exportxmlNodePtrandothertypesin"CCUserDefault.h"
*/

statictinyxml2::XMLElement*getXMLNodeForKey( checkthekeyvalue if(!pKey)
{
returnnullptr;
}

do
{
tinyxml2::XMLDocument*xmlDoc= newtinyxml2::XMLDocument();
*doc=xmlDoc;

std:: stringxmlBuffer=FileUtils::getInstance()->getStringFromFile(UserDefault::getInstance()->getXMLFilePath());

if(xmlBuffer.empty())
{
CCLOG("cannotreadxmlfile");
break;
}
xmlDoc->Parse(xmlBuffer.c_str(),xmlBuffer.size());

getrootnode
*rootNode=xmlDoc->RootElement();
if(nullptr==*rootNode)
{
CCLOG("readrootnodeerror");
break;
}

curNode=(*rootNode)->FirstChildElement();
while(nullptr!=curNode)
{
char*nodeName=curNode->Value();
if(!strcmp(nodeName,pKey))
{
break;
}

curNode=curNode->NextSiblingElement();
}
} while(0);

returncurNode;
}
关于setValueForKey的实现
static voidsetValueForKey( char*pValue)
{
tinyxml2::XMLElement*rootNode;
tinyxml2::XMLDocument*doc;
tinyxml2::XMLElement*node;
checktheparams if(!pKey||!pValue)
{
return;
}

node=getXMLNodeForKey(pKey,0)">ifnodeexist,changethecontent if(node)
{
if(node->FirstChild())
{
node->FirstChild()->SetValue(pValue);
}
else
{
tinyxml2::XMLText*content=doc->NewText(pValue);
node->LinkEndChild(content);
}
}
else
{
if(rootNode)
{
tinyxml2::XMLElement*tmpNode=doc->NewElement(pKey); newtinyxml2::XMLElement(pKey);
rootNode->LinkEndChild(tmpNode);
tinyxml2::XMLText*content=doc->NewText(pValue); newtinyxml2::XMLText(pValue);
tmpNode->LinkEndChild(content);
}
}

savefileandfreedoc if(doc)
{
doc->SaveFile(UserDefault::getInstance()->getXMLFilePath().c_str());
deletedoc;
}
}
它的flush方法也有惊人的发现:
voidUserDefault::flush()
{
}
它是一个空函数,也就是说,你在写入数据的时候,会以为最后会通过flush才会写入数据,没想全错了!
如果你用它存贮比较多的字段时,你就会现,你悲剧了。
幸好发现及时,这里不建议大家使用UserDefault做为你的数据存贮。
可以可以用自定义的方式文件读写
如可以通过标准的C读写 fopen,fwrite等或iostream也都可以,重点是读写的文件路径,会有所不同,下面是得到文件路径的例子
std::string strFullFileName = FileUtils::getInstance()->getWritablePath() + DATA_FILE_NAME; 最后:不要求写太高质量的代码,但也不要写的太低质量了

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