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;
}
}