NSUserDefaults適合存儲輕量級的本地數據,比如要保存一個登陸界面的數據,用戶名、密碼之類的,個人覺得使用NSUserDefaults是首選。下次再登陸的時候就可以直接從NSUserDefaults里面讀取上次登陸的信息。
因為如果使用自己建立的plist文件什么的,還得自己顯示創建文件,讀取文件,很麻煩,而是用NSUserDefaults則不用管這些東西,就像讀字符串一樣,直接讀取就可以了。
NSUserDefaults支持的數據格式有:NSNumber(Integer、Float、Double),NSString,NSDate,NSArray,NSDictionary,BOOL類型。
NSUserDefaults常用的方法
NSUserDefaults常用的方法,使用和NSMutableDictionary的一些方法類似。
//設置
- (void)setInteger:(NSInteger)value forKey:(NSString *)defaultName;
- (void)setFloat:(float)value forKey:(NSString *)defaultName;
- (void)setDouble:(double)value forKey:(NSString *)defaultName;
- (void)setBool:(BOOL)value forKey:(NSString *)defaultName;
- (void)setURL:(nullable NSURL *)url forKey:(NSString *)defaultName NS_AVAILABLE(10_6, 4_0);
- (void)setObject:(nullable id)value forKey:(NSString *)defaultName;
//獲取
- (nullable NSString *)stringForKey:(NSString *)defaultName;
- (nullable NSArray *)arrayForKey:(NSString *)defaultName;
- (nullable NSDictionary*)dictionaryForKey:(NSString *)defaultName;
- (nullable NSData *)dataForKey:(NSString *)defaultName;
- (nullable NSArray*)stringArrayForKey:(NSString *)defaultName;
- (NSInteger)integerForKey:(NSString *)defaultName;
- (float)floatForKey:(NSString *)defaultName;
- (double)doubleForKey:(NSString *)defaultName;
- (BOOL)boolForKey:(NSString *)defaultName;
- (nullable NSURL *)URLForKey:(NSString *)defaultName NS_AVAILABLE(10_6, 4_0);
//這里建議同步存儲到磁盤中
[userDefaults?synchronize];
調用set的方法后,如果需要馬上同步synchronize方法。注意這個方法不要太頻繁調用。如果不調用synchronize,系統會每個一個時間段自動保存。
//保存數據到NSUserDefaults
-(void)saveNSUserDefaults
{
NSString?*myString?=?@"enuola";
int?myInteger?=?100;
float?myFloat?=?50.0f;
double?myDouble?=?20.0;
NSDate?*myDate?=?[NSDate?date];
NSArray?*myArray?=?[NSArray?arrayWithObjects:@"hello",?@"world",?nil];
NSDictionary?*myDictionary?=?[NSDictionary?dictionaryWithObjects:[NSArray?arrayWithObjects:@"enuo",?@"20",?nil]?forKeys:[NSArray?arrayWithObjects:@"name",?@"age",?nil]];
//將上述數據全部存儲到NSUserDefaults中
NSUserDefaults?*userDefaults?=?[NSUserDefaults?standardUserDefaults];
//存儲時,除NSNumber類型使用對應的類型意外,其他的都是使用setObject:forKey:
[userDefaults?setInteger:myInteger?forKey:@"myInteger"];
[userDefaults?setFloat:myFloat?forKey:@"myFloat"];
[userDefaults?setDouble:myDouble?forKey:@"myDouble"];
[userDefaults?setObject:myString?forKey:@"myString"];
[userDefaults?setObject:myDate?forKey:@"myDate"];
[userDefaults?setObject:myArray?forKey:@"myArray"];
[userDefaults?setObject:myDictionary?forKey:@"myDictionary"];
//這里建議同步存儲到磁盤中,但是不是必須的
[userDefaults?synchronize];
}
//從NSUserDefaults中讀取數據
-(void)readNSUserDefaults
{
NSUserDefaults?*userDefaultes?=?[NSUserDefaults?standardUserDefaults];
//讀取整型int類型的數據
NSInteger?myInteger?=?[userDefaultes?integerForKey:@"myInteger"];
//讀取浮點型float類型的數據
float?myFloat?=?[userDefaultes?floatForKey:@"myFloat"];
//讀取double類型的數據
double?myDouble?=?[userDefaultes?doubleForKey:@"myDouble"];
//讀取NSString類型的數據
NSString?*myString?=?[userDefaultes?stringForKey:@"myString"];
//讀取NSDate日期類型的數據
NSDate?*myDate?=?[userDefaultes?valueForKey:@"myDate"];
NSDateFormatter?*df?=?[[NSDateFormatter?alloc]?init];
[df?setDateFormat:@"yyyy-MM-dd?HH:mm:ss"];
txtNSDate.text?=?[NSString?stringWithFormat:@"%@",[df?stringFromDate:myDate]];
//讀取數組NSArray類型的數據
NSArray?*myArray?=?[userDefaultes?arrayForKey:@"myArray"];
NSString?*myArrayString?=?[[NSString?alloc]?init];
for(NSString?*str?in?myArray)
{
NSLog(@"str=?%@",str);
myArrayString?=?[NSString?stringWithFormat:@"%@??%@",?myArrayString,?str];
[myArrayString?stringByAppendingString:str];
//????????[myArrayString?stringByAppendingFormat:@"%@",str];
NSLog(@"myArrayString=%@",myArrayString);
}
//讀取字典類型NSDictionary類型的數據
NSDictionary?*myDictionary?=?[userDefaultes?dictionaryForKey:@"myDictionary"];
NSString?*myDicString?=?[NSString?stringWithFormat:@"name:%@,?age:%d",[myDictionary?valueForKey:@"name"],?[[myDictionary?valueForKey:@"age"]?integerValue]];
}
再次運行的時候,讓程序直接讀取而不存儲數據,發現以前保存的數據仍然可以讀取到界面上。
下面講一下原理:
你可能會問一個問題:NSUserDefautls將數據存儲在什么地方了???我都沒有顯示的指定路徑???很疑惑吧。。。。
用NSUserDefaults存儲的數據下次程序運行的時候依然存在,它把數據存儲在什么地方了?如何能夠清除?
其實它存儲在應用程序內置的一個plist文件里,這個可以根據路徑看到。
比如說這個是你的程序沙盒位置
/UsersLibrary/Application Support/iPhoneSimulator/4.1/Applicati*****/29788E40-AF47-45A0-8E92-3AC0F501B7F4/,(這個是應用程序對應在mac上的位置)
這個下面有/Library/Prefereces,里面有個plist文件,存儲的就是你的userDefaults
想要刪掉的話,用removeObjectForKey或者刪掉沙盒,也就是你的應用程序然后重新安裝。
數據共享
//appA中
NSUserDefaults *shareDefaultA = [[NSUserDefaults alloc]initWithSuiteName:@"com.storage.demo"];
[shareDefaultA setObject:@"appA"forKey:@"shareKey"];
//appB中
NSUserDefaults *shareDefaultB = [[NSUserDefaults alloc]initWithSuiteName:@"com.storage.demo"];
NSString*value = [shareDefaultB objectForKey:@"shareKey"];
這里就能解釋,同一個公司的app,裝了一個之后,在裝另一個,就會自動登錄的功能。initWithSuiteName會在Library/Preference下新建一個以name為名字的plist文件。[NSUserDefaults standardUserDefaults]是以bundle id為名字的一個plist文件。利用這個我們可以給每一個用戶新建一個偏好設置的文件,保存皮膚,字體等,不同的用戶登錄就會有不同的效果。
NSUserDefaults數據清除
- (void)removePersistentDomainForName:(NSString *)domainName;
清除domain下的所有信息。在這里要說一下NSUserDefaults的域,默認包含5個domain,分別是NSArgumentDomain,Application,NSGlobalDomain,Languages,NSRegistrationDomain。
//清除Application所有的偏好設置,如果domainName是initWithSuiteName的name,則清除name對應的plist文件的內容
NSString *appDomain =[[NSBundle mainBundle]bundleIdentifier];
[[NSUserDefaults standardUserDefaults]removePersistentDomainForName:appDomain];
NSUserDefaults注意的地方
當我們獲取偏好設置的值的時候,需要注意,比如如下:[standboolForKey:@"key1"];如果沒有對應的key1則獲取的值為默認值false。這種情況就有可能和有對應的key,并且對應的值為false時,區分不開,造成的邏輯錯誤。類似的還有[standintegerForKey:@""]等。
對應的解決辦法是:
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@"true",@"test",@"3",@"inter", nil]; ? ? ? ? ? ? ? ? ? ? ? ? ? ?//注冊一個默認的字典
[stand registerDefaults:dict];
BOOL isok= [stand boolForKey:@"test"];
NSInteger inter= [stand integerForKey:@"inter"];
NSLog(@"%d,,,,%ld",isok,(long)inter);