今天遇到新生問一個問題,就是用自己定義了一個plist文件,然后可以往里面寫東西,但是寫過再次運行的時候里面的數據總是最后一次寫入的數據。后來就專門研究了一下plist文件。
大家都知道當你創建一個項目的時候,在Supporting Files中會有一個Info.plist文件,這個文件中存儲的信息如下:
它是整個APP的配置文件,包括了版本信息以及APP桌面顯示名稱等信息。可能是我還不太了解,但是經過我測試發現我無法用代碼對Info.plist這個文件進行操作。
先把plist文件放在一邊,先了解一下文件目錄,這個我認為很必要。直接看下圖:
我已經在上面都標注了一下用到的文件夾以及文件的作用,相信大家應該對整個目錄結構有一個整體的了解。現在繼續談談plist文件。
用例子說明:比如我要做一個通訊錄,想用plist文件去存放每個人的基本信息,包括姓名和電話。想要實現的最終效果是:
那么我就可以這樣做:
- (void)viewDidLoad { [super viewDidLoad]; NSString *rootPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject; NSString *path = [rootPath stringByAppendingPathComponent:@"user.plist"]; NSMutableArray *totalArr = [[NSMutableArray alloc] initWithContentsOfFile:path]; if(!totalArr) { totalArr = [NSMutableArray new]; } NSMutableDictionary *dic = [NSMutableDictionary new]; [dic setObject:@“183434534535" forKey:@"telephone"]; [dic setObject:@“王五" forKey:@“name"]; [totalArr addObject:dic]; [totalArr writeToFile:path atomically:YES]; }
第一步:我先獲得剛才所說的那個存放我們自己創建的文件的目錄Documents。
NSString *rootPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
第二步:相當於字符串拼接,獲取那個user.plist的絕對路徑。
NSString *path = [rootPath stringByAppendingPathComponent:@"user.plist"];
第三步:我新建一個NSMutableArr,里面的數據來自於path所指向的文件,即plist文件。這樣的話文件中的數據就可以寫到totalArr中了
NSMutableArray *totalArr = [[NSMutableArray alloc] initWithContentsOfFile:path]; if(!totalArr) { totalArr = [NSMutableArray new]; }
注意,這里可能user.plist文件不存在,所以如果這個文件不存在,那么totalArr是沒有創建成功的,所以加一個判斷,如果totalArr沒有創建成功(因為path下沒有這個文件),就新建一個。
第四步:新建一個字典,然后把字典放到totalArr中。

NSMutableDictionary *dic = [NSMutableDictionary new]; [dic setObject:@“183434534535" forKey:@"telephone"]; [dic setObject:@“王五" forKey:@“name"]; [totalArr addObject:dic]; //這里我把新建的dic加入原來的數組中,這樣就會把原來的數據也一並寫入到plist文件中.
第五步:將totalArr寫入plist文件中。
[totalArr writeToFile:path atomically:YES];
注意:如果path下地那個文件不存在,這個writeToFile方法會自動創建一個user.plist文件。然后將totalArr中的數據寫進去。
這樣就完成了。
注意:plist文件寫入時(即[totalArr writeToFile:path atomically:YES];),會先清空整個plist文件,然后從新將totalArr寫到里面,所以為了保存原來寫入的數據,需要在原來數組的基礎上再加入一個新的dic( [totalArr addObject:dic]; ),這樣就可以把原來的數據一塊寫入了。
也許你會想直接在Supporting Files中新建一個plist文件不行么?答案是不行。具體原因可能如下:
從上圖可以看出,我新建的plist文件在項目文件夾下,根本沒有在沙盒中。而且雖然我可以對這個文件進行讀操作(用NSBundle操作),但是經過測試發現無法對其進行操作,具體原因不太清楚。
但是我用
NSString *testPath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"plist”];
去獲取testPath時發現它的路徑如下:
/Users/admin/Library/Developer/CoreSimulator/Devices/F73D2947-21CC-4E8E-AE3E-D80E6652D840/data/Containers/Bundle/Application/C77E606F-AB5B-425A-BD2F-BC7B6B078187/test.app/test.plist
仔細觀察,原來這個文件是test.app中的文件,這樣也合情理,因為這個test.app就是應用程序。我用上面的寫入方法去寫入數據時,發現我打開test.app下地test.plist。里面確實有數據,也就是說我把數據寫進去了,但是當我查看Supporting Files文件夾下那個test.plist時,里面沒有數據。而在次運行程序時,那個test.app會重新生成。里面的數據也都消失了。
修訂記錄:
1、整理的了解------->整體的了解(2017年5月15日上午10:15修改)