儲存玩家資料,模拟器讀寫都可以,而真機plist檔案隻能讀不能寫,十分頭大,弄球一天找到了問題所在。
按照網上比較有說服力的說法是:iOS程式執行的時候是在“沙盒”裡執行。而沙盒裡的資料不能寫入,隻能讀取。
經過測試,當一個程式在執行的時候,比如叫 Test.app 的iOS程式,獲得他的執行位址的代碼是(比如找的是CFG.plist檔案)
NSBundle *bundle = [ NSBundle mainBundle ];
NSString *filePath = [ bundle pathForResource:@"CFG" ofType:@"plist" ];
filePath列印出來的執行位址應該類似
Support/iPhone Simulator/5.0/Applications/3B5DBF75-18D2-43EA-B26F-7FEDECAFDC92/Test.app/CFG.plist
每 個應用程式都一個固定且唯一的ID(上面的3B5DBF75-18D2-43EA-B26F-7FEDECAFDC92),這個ID被作為iOS執行時的 一個用來修飾的檔案夾,這樣可以保證每個應用都是獨立的,哪怕名字一樣。而這個ID檔案夾下有一系列實際存在的檔案夾。而Test.app隻是其中一個, 裡面有實際的遊戲資料。如果要想儲存資料,那麼應該将資料寫入到一個叫做“Documents”的檔案夾下。通路路徑的代碼如下:
NSArray *doc = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *docPath = [ doc objectAtIndex:0 ];
執行結果是 Support/iPhone Simulator/5.0/Applications/3B5DBF75-18D2-43EA-B26F-7FEDECAFDC92/Documents
可以看到系統檔案名ID和上面的一樣。
綜 上所述。當有資料為隻讀的時候,應該放到app應用裡的plist裡,當資料要做修改,應該放到documents裡。比如遊戲裡的物品資料,這種不能被 修改的放到app裡,而玩家的合成裝備應該在documents裡手動建立一個plist來存儲。那麼首要問題就是要判斷,documents裡是否已有 資料。
NSArray *doc = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [ doc objectAtIndex:0 ];
if( [[NSFileManager defaultManager] fileExistsAtPath:[docPathstringByAppendingPathComponent:@"Score.plist"] ]==NO ) {
// ============================== 寫入plist初始化資料(最後有,先說讀取)
}
讀取:
NSArray *doc = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [ doc objectAtIndex:0 ]; // 字典集合。
NSDictionary *dic = [ NSDictionary dictionaryWithContentsOfFile:[docPathstringByAppendingPathComponent:@"Score.plist"] ]; // 解析資料
NSString *content = [ dic objectForKey:@"Score" ];
NSArray *array = [ content componentsSeparatedByString:@","];
content裡就是“Score”裡所存儲的資料,array是将content裡的資料按“,”拆分,僅将兩個“,”之間的資料儲存。
寫入:一定要注意,必須建立一個新的NSMutableDictionary
// 用來覆寫原始資料的新dic
NSMutableDictionary *newDic = [ [ NSMutableDictionary alloc ] init ];
// 新資料
NSString *newScore = @"100,200,300";
// 将新的dic裡的“Score”項裡的資料寫為“newScore”
[ newDic setValue:newScore forKey:@"Score" ];
// 将 newDic 儲存至docPath+“Score.plist”檔案裡,也就是覆寫原來的檔案
NSArray *doc = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docPath = [ doc objectAtIndex:0 ];
[ newDic writeToFile:[docPath stringByAppendingPathComponent:@"Score.plist"] atomically:YES ];