目錄
- 什么是Plist文件?
- plist可以存儲哪些數據類型
- plist文件數據的讀取與存儲
- Perference(NSUserDefaults)
- 使用方法
- registerDefaults: 方法的使用
什么是Plist文件?
Plist文件(屬性列表)是將某些特定的類,通過XML文件的方式保存在目錄中。
什么是 XML?
可擴展標記語言 (XML) 允許您以可共享的方式定義和存儲數據。XML 支持計算機系統(如網站、數據庫和第三方應用程序)之間的信息交換。預定義的規則簡化了在任何網絡上以 XML 文件的形式傳輸數據的過程,接收者可以使用這些規則準確高效地讀取數據。
我們以 Xcode自動生成的plist文件為例,觀察其結構,當我們新建一個項目時后,會發現有一個Info.plist文件,里面有很多參數和配置:
這是Xcode為我們自動生成的plist文件,用來保存當前項目的一些配置,Xcode為ta集成了很多預置的Key
和Value
右鍵Info.plist文件->Open As->Source Code,用文本編輯器打開plist文件:
可以看到plist文件就是一個XML文件,key
為鍵,string
為對應的值
plist可以存儲哪些數據類型
可以發現每一個鍵值對中間都有一個Type
,不難理解這就是value的類型,右鍵查看:
plist文件可以被序列化的類型(可以被存儲的類型)只有這幾種:基本數據類型(NSString
、NSNumber
、NSDate
、BOOL
),對象數據類型(NSData/NSMutableData
),集合類型(NSArray/NSMutableArray
、NSDictionary/NSMutableDictionary
),不能保存自定義對象
不難理解,這些數據可以被轉換保存到一個純文本文件(區別于二進制文件)中
plist文件數據的讀取與存儲
1. 讀取
一般情況下,plist文件
存儲在沙盒的 /Documents中,所以要獲取某個plist文件,只需要知道其文件名即可。用過以下方法獲取plist數據(一般以NSArray或NSDictionary的形式保存):
//獲取文件路徑
NSString* path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString* fileName = [path stringByAppendingPathComponent: @"filename.plist"];//提取plist數據
NSArray* result = [NSArray arrayWithContentsOfFile: fileName];
NSLog(@"%@", result);
2. 存儲
往plist文件寫入數據直接用相應類型的writeToFile:
方法即可
NSArray* array = @[@"ott", @"123", @"abc"];
[array writeToFile: fileName atomically: YES];
writeToFile: atomically:
方法中atomically
表示是否需要先寫入一個輔助文件,再把輔助文件拷貝到目標文件地址,更安全的寫入文件,一般該值為YES
運行后,Documents目錄:
array以XML格式保存在本地
這個方法也可用于其他數據文件(.plist
、.txt
、.data
等格式的文件),在沙盒中指定某一路徑,新建并將數據文件保存在這一路徑(同樣,自定義對象是不能直接存入的,但是可以通過歸檔存為.data
文件)
Perference(NSUserDefaults)
Perference(偏好設置)顧名思義就是專門用來存儲系統的偏好配置、用戶設置的參數和App的狀態等少量信息的,一般不保存其他數據
使用NSUserDefaults
類,以字典形式保存數據,iOS會自動把字典中的鍵值對轉換成對應的XML文件(也就是plist文件),該文件存放在沙盒的 /Library/Preferences/ 目錄下
NSUserDefaults
是單例類,此類實際上就是對plist文件操作進行了封裝,更方便我們直接操作
使用方法
- 獲取NSUserDefaults文件
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
- 向plist文件寫入內容
[userDefaults setObject: @"3G!!!" forKey: @"obj"];
[userDefaults setBool: YES forKey: @"isMale"];
[userDefaults setInteger: 20 forKey: @"age"];
- 立即同步
[userDefaults synchronize];
如果沒有調用synchronize
方法,系統會根據I/O情況(讀取、寫入和更新)不定時刻地將數據保存到文件中(以周期性間隔自動調用的同步方法使內存中的緩存與用戶的默認數據庫保持同步,而不是及時寫入的),所以為防止在寫完NSUserDefaults
后程序退出導致數據丟失,需要立即寫入文件的話就必須調用synchronize
方法
- 讀取文件中的內容
NSString* userName = [userDefaults objectForKey: @"obj"];
BOOL genderIsMale = [userDefaults boolForKey: @"isMale"];
NSInteger age = [userDefaults integerForKey: @"age"];
NSLog(@"%@ %d %ld", userName, genderIsMale, age);
[userDefaults removeObjectForKey: @"isMale"];
這樣就會將所有數據保存到同一個文件中(即Preference目錄下的一個以此應用包名稱來命名的plist文件):
注:
返回值從NSUserDefaults是不可改變的,即使設置一個值可變對象。 例如,如果設置一個可變的字符串值作為"MyStringDefault",則稍后使用stringForKey:檢索的字符串將是不可變的
registerDefaults: 方法的使用
NSUserDefaults除了保存和讀取功能外,還為我們提供了一個很便捷的方法:registerDefaults:
ta的參數是一個字典類型,作用僅僅是為了定義一組默認的數據,這些默認的數據是不會被保存到plist文件中的,我們需要手動變更這些數據然后保存
舉一個例子,我們可以使用這個方法來確認App是否是第一次啟動:
//注冊一個默認值
[userDefaults registerDefaults: @{@"firstRun" : @YES}];//第一次啟動還沒有生成plist文件,就會讀取上面注冊的默認值
BOOL isFirstRun = [userDefaults boolForKey: @"firstRun"];//是第一次啟動
if (isFirstRun) {NSLog(@"這是第一次啟動");//手動改為NO,保存到plist文件中[userDefaults setBool: NO forKey: @"firstRun"];
} else {NSLog(@"不是第一次啟動");
}
再次強調,registerDefaults
方法中的字典數據是不會保存到plist文件中的,當我們讀取某個鍵值時,如果沒有plist文件或plist文件中沒有找到對應的鍵值,那么就會從registerDefaults
方法的字典參數中尋找對應的鍵值,拿到默認值。
當我們做了相應處理后,再手動把這個鍵值內容保存到plist中,下次讀取就會是直接讀取plist文件中的鍵值,而不是讀取registerDefaults
中參數的字典內容了