[cocos2dx笔记016]cocos2dx 3.2 的UserDefault
发布时间:2020-12-14 17:00:13 所属栏目:百科 来源:网络整理
导读:本文地址:http://www.cppblog.com/zdhsoft/archive/2014/09/03/208216.html 本文基于cocos2dx 3.2 cocos2dx 提供了一个基于xml的用户数据存贮类,给基于cocos2dx开发的用户数据存贮,这个类名就是UserDefault,在cocos2dx 2.x中是CCUserDefault。我的程序用
本文地址: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)
关于getXMLNodeForKey的实现
{ 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; } /* * *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; 最后:不要求写太高质量的代码,但也不要写的太低质量了 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |