UserDefault类是用来为Cocos2dx配置程序的一些简单信息来使用的.内部是通过键值对的形式写入到xml文件中去.关于UserDefault的用法非常的简单,基本看一遍就会了.通过set和get修改和获取变量.
它可以用来保存bool,int,float,double,string等类型.Data类型我在之前的博客简单的介绍过了,就是相当于C风格字符串的类型.主要有下面两个成员变量.
unsigned char* _bytes;
ssize_t _size;
但是UserDefault生成的XML文件的路径问题,问题就挺多了.下面是没有我没有手动修改过写入路径后打印的路径:
log("%s", FileUtils::getInstance()->getWritablePath().c_str());
C:/Users/TF/AppData/Local/test/
test是我测试用的程序.系统自动保存到了这个路径下…AppData还是隐藏起来的.
我们可以在该路径下找到此文件.打开内容一看.是那熟悉的XML配置.
我们可以通过修改FileUtils,也就是文件工具类的可写入路径来修改该XML的产生路径.Data是我创建的一个文件夹.
FileUtils::getInstance()->setWritablePath("C:/Users/TF/Desktop/test/proj.win32/Data/");
现在我们学会了修改写入路径来修改XML文件的位置.那么就会出现这么一个有趣的问题.如果在程序运行之初,我们修改过了一次写入路径.然后使用UserDefaut保存了一些键值对.之后我们又去修改了写入路径,然后再保存了一些键值对.那么会出现怎么样的情况呢?是在不同的路径产生两个XML文件,还是怎么样呢?
我们先看一下结果.再去分析产生的原因.测试代码如下:
这FileUtils::getInstance()->setWritablePath("C:/Users/TF/Desktop/test/proj.win32/Data/");
UserDefault::getInstance()->setBoolForKey("first",true);
//修改了写入路径,然后增加保存新的键值对.
FileUtils::getInstance()->setWritablePath("C:/Users/TF/Desktop/test/proj.win32");
UserDefault::getInstance()->setBoolForKey("next", false);
可以看到只在第一次修改可写入数据的时候,才产生了XML文件.
且两次键值对都成功保存了.
<?xml version="1.0" encoding="UTF-8"?>
<userDefaultRoot>
<first>true</first>
<next>false</next>
</userDefaultRoot>
那么产生的原因我们可以通过阅读源码去给自己解惑:由于UserDefault是单例设计的,所以在第一次调用getInstance()时,就进行初始化了.下面是初始化实例的源码.主要进行了initXMLFilePath()这个方法.如果XML文件存在则直接返回.
UserDefault* UserDefault::getInstance()
{
if (!_userDefault)
{
initXMLFilePath();
// only create xml file one time
// the file exists after the program exit
if ((!isXMLFileExist()) && (!createXMLFile()))
{
return nullptr;
}
_userDefault = new (std::nothrow) UserDefault();
}
return _userDefault;
}
下面是initXMLFilePath()方法的源码._filePath是由FileUtils的可写入路径+XML文件名来初始化的.而_filePath我们找到定义发现默认是空字符串.也就是说它是用来保存XML文件的路径的成员变量.且在第一次实例化时才被初始化赋值为用户自定义的可写入路径.
string UserDefault::_filePath = string("");
void UserDefault::initXMLFilePath()
{
if (! _isFilePathInitialized)
{
_filePath += FileUtils::getInstance()->getWritablePath() + XML_FILE_NAME;
_isFilePathInitialized = true;
}
}