IOS-本地存儲(chǔ)-NSUserDefaults
一 NSUserDefaults簡(jiǎn)介
NSUserDefaults類(lèi)提供了一個(gè)與默認(rèn)系統(tǒng)進(jìn)行交互的編程接口。NSUserD efaults對(duì)象是用來(lái)保存、恢復(fù)應(yīng)用程序相關(guān)的偏好設(shè)置、配置數(shù)據(jù)等等。默認(rèn)系統(tǒng)允許應(yīng)用程序自定義它的行為去迎合用戶(hù)的喜好。你可以在程序運(yùn)行的時(shí)候從用戶(hù)默認(rèn)的數(shù)據(jù)庫(kù)中讀取程序的設(shè)置,同時(shí)NSUserDefaults的緩存避免了在每次讀取數(shù)據(jù)時(shí)候都打開(kāi)用戶(hù)默認(rèn)數(shù)據(jù)庫(kù)的操作??梢酝ㄟ^(guò)調(diào)用synchroni ze方法來(lái)使內(nèi)存中的緩存與用戶(hù)默認(rèn)系統(tǒng)進(jìn)行同步。NSUserDefaults類(lèi)提供了非常方便的方法來(lái)讀寫(xiě)常用的類(lèi)型,常用的方法有:setBool:forKey、setFloat :forKey、setInteger:forKey、setObject:forKey、setDouble:forKey、setURL:forKey,具體使用哪個(gè)方法取決于要存儲(chǔ)的數(shù)據(jù)類(lèi)型。其中,方法setObject: forKey用于存儲(chǔ)NSString、NSDate、NSArry、NSDictionary等復(fù)合對(duì)象類(lèi)型。
二 實(shí)例代碼
NSUserDefaults是單例,同時(shí)也是線(xiàn)程安全的。使用方法如下:
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setBool: self.toggleSwitch.on forKey:kOnOffToggle];
[userDefaults setFloat: self.brightnessSlider.value forKey:kBrightnessLevel];
注意:上述代碼將數(shù)據(jù)寫(xiě)入默認(rèn)設(shè)置數(shù)據(jù)庫(kù)時(shí),并不一定會(huì)立即保存這些數(shù)據(jù)。還需要進(jìn)一步調(diào)用 synchronize 方法確保所有數(shù)據(jù)都及時(shí)寫(xiě)入:
[userDefaultssynchronize];
要將這些數(shù)據(jù)讀入 App 中,可根據(jù)鍵值和返回類(lèi)型,調(diào)用相應(yīng)的方法。根據(jù)要讀取的數(shù)據(jù)類(lèi)型,可選擇 arrayForKey、boolForKey、dateforKey、 dictionaryForKey、 floatForKey、integerForKey、objectForKey、doubleForKey和URLForKey等方法。
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
self.brightnessSlider.value = [userDefaults floatForKey:kBrightnessLevel];
self.toggleSwitch.on = [userDefaults boolForKey:kOnOffToggle];
NSUserDefaults適合存儲(chǔ)輕量級(jí)的本地?cái)?shù)據(jù),比如要保存一個(gè)登陸界面的數(shù)據(jù),用戶(hù)名、密碼之類(lèi)的,個(gè)人覺(jué)得使用NSUserDefaults是首選。下次再登陸的時(shí)候就可以直接從NSUserDefaults里面讀取上次登陸的信息。
因?yàn)槿绻褂米约航⒌膒list文件什么的,還得自己顯示創(chuàng)建文件,讀取文件,很麻煩,而是用NSUserDefaults則不用管這些東西,就像讀字符串一樣,直接讀取就可以了(NSUserDefaults中的數(shù)據(jù)最終都會(huì)存儲(chǔ)到plist屬性列表里面)。NSUserDefaults支持的數(shù)據(jù)格式有:NSNumber(Integer、Float、Double),NSString,NSDate,NSArray,NSDictionary,BOOL類(lèi)型。
NSUserDefaults很方便,讀取也很容易。下面給出一個(gè)示例看看如何使用,ViewController.h文件中主要是放幾個(gè)控件,用于顯示存儲(chǔ)的數(shù)據(jù):
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
{
IBOutlet UILabel *txtInteger;
IBOutlet UILabel *txtFloat;
IBOutlet UILabel *txtDouble;
IBOutlet UILabel *txtNSString;
IBOutlet UILabel *txtNSDate;
IBOutlet UILabel *txtNSArray;
IBOutlet UILabel *txtNSDictionary;
}
@end
ViewController.m文件中最重要的是兩個(gè)方法:
saveNSUserDefaults:用于將各種類(lèi)型數(shù)據(jù)保存到NSUserDefaults中
readNSUserDefautls:用于從NSUserDefaults中讀取各種類(lèi)型的數(shù)據(jù)。在viewDidLoad中調(diào)用這兩個(gè)方法就可以看出結(jié)果咯
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self saveNSUserDefaults]; //調(diào)用此方法將各種數(shù)據(jù)存儲(chǔ)到NSUserDefautls中,在下面定義
[self readNSUserDefaults]; //調(diào)用此方法從NSUserDefautls中讀取各種數(shù)據(jù),在下面定義
}
- (void)viewDidUnload
{
[txtNSString release];
txtNSString = nil;
[txtNSDate release];
txtNSDate = nil;
[txtNSArray release];
txtNSArray = nil;
[txtNSDictionary release];
txtNSDictionary = nil;
[txtInteger release];
txtInteger = nil;
[txtFloat release];
txtFloat = nil;
[txtDouble release];
txtDouble = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
}
//保存數(shù)據(jù)到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]];
//將上述數(shù)據(jù)全部存儲(chǔ)到NSUserDefaults中
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
//存儲(chǔ)時(shí),除NSNumber類(lèi)型使用對(duì)應(yīng)的類(lèi)型意外,其他的都是使用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"];
//這里建議同步存儲(chǔ)到磁盤(pán)中,但是不是必須的
[userDefaults synchronize];
}
//從NSUserDefaults中讀取數(shù)據(jù)
-(void)readNSUserDefaults
{
NSUserDefaults *userDefaultes = [NSUserDefaults standardUserDefaults];
//讀取數(shù)據(jù)到各個(gè)label中
//讀取整型int類(lèi)型的數(shù)據(jù)
NSInteger myInteger = [userDefaultes integerForKey:@"myInteger"];
txtInteger.text = [NSString stringWithFormat:@"%d",myInteger];
//讀取浮點(diǎn)型float類(lèi)型的數(shù)據(jù)
float myFloat = [userDefaultes floatForKey:@"myFloat"];
txtFloat.text = [NSString stringWithFormat:@"%f",myFloat];
//讀取double類(lèi)型的數(shù)據(jù)
double myDouble = [userDefaultes doubleForKey:@"myDouble"];
txtDouble.text = [NSString stringWithFormat:@"%f",myDouble];
//讀取NSString類(lèi)型的數(shù)據(jù)
NSString *myString = [userDefaultes stringForKey:@"myString"];
txtNSString.text = myString;
//讀取NSDate日期類(lèi)型的數(shù)據(jù)
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]];
//讀取數(shù)組NSArray類(lèi)型的數(shù)據(jù)
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);
}
txtNSArray.text = myArrayString;
//讀取字典類(lèi)型NSDictionary類(lèi)型的數(shù)據(jù)
NSDictionary *myDictionary = [userDefaultes dictionaryForKey:@"myDictionary"];
NSString *myDicString = [NSString stringWithFormat:@"name:%@, age:%d", [myDictionary valueForKey:@"name"], [[myDictionary valueForKey:@"age"] integerValue]];
txtNSDictionary.text = myDicString;
}
@end
好了,運(yùn)行一下,可以看到xib文件中的各種數(shù)據(jù)已經(jīng)綁定上了吧?
再次運(yùn)行的時(shí)候,可以把viewDidLoad中的 [self saveNSUserDefaults]; 這一行注釋掉,讓程序直接讀取而不存儲(chǔ)數(shù)據(jù),發(fā)現(xiàn)以前保存的數(shù)據(jù)仍然可以讀取到界面上。
用NSUserDefaults存儲(chǔ)的數(shù)據(jù)下次程序運(yùn)行的時(shí)候依然存在,它把數(shù)據(jù)存儲(chǔ)在什么地方了?如何能夠清除?其實(shí)它存儲(chǔ)在應(yīng)用程序內(nèi)置的一個(gè)plist文件里,這個(gè)可以根據(jù)路徑看到。比如說(shuō)這個(gè)是你的程序沙盒位置: /Users/Library/Application Support/iPhoneSimulator/4.1/Applicati*****/29788E40-AF47-45A0-8E92-3AC0F501B7F4/,(這個(gè)是應(yīng)用程序?qū)?yīng)在mac上的位置)這個(gè)下面有/Library/Prefereces,里面有個(gè)plist文件,存儲(chǔ)的就是你的userDefaults想要?jiǎng)h掉的話(huà),用removeObjectForKey或者刪掉沙盒,也就是你的應(yīng)用程序然后重新安裝。
三 注意問(wèn)題
1、UserDefaults是根據(jù)時(shí)間戳定時(shí)的把緩存中的數(shù)據(jù)寫(xiě)入本地磁盤(pán),而非即時(shí)寫(xiě)入。為了防止數(shù)據(jù)丟失,我們?cè)趯?duì)重要的數(shù)據(jù)保存時(shí)使用synchornize方法強(qiáng)制寫(xiě)入。但是也要注意,不用頻繁的使用synchornize,這樣畢竟影響性能和效率,
2、IOS本地存儲(chǔ)位置說(shuō)明
| 1 | 2 |
|---|---|
| <Application_Home>/Documents/ | 您應(yīng)該將所有的應(yīng)用程序數(shù)據(jù)文件寫(xiě)入到這個(gè)目錄下。這個(gè)目錄用于存儲(chǔ)用戶(hù)數(shù)據(jù)或其它應(yīng)該定期備份的信息。有關(guān)如何取得這個(gè)目錄路徑的信息,請(qǐng)參見(jiàn)“獲取應(yīng)用程序目錄的路徑”部分。iTunes會(huì)備份這個(gè)目錄的內(nèi)容。 |
| <Application_Home>/Library/Preferences | 這個(gè)目錄包含應(yīng)用程序的偏好設(shè)置文件。您不應(yīng)該直接創(chuàng)建偏好設(shè)置文件,而是應(yīng)該使用NSUserDefaults類(lèi)或CFPreferences API來(lái)取得和設(shè)置應(yīng)用程序的偏好,詳情請(qǐng)參見(jiàn)“添加Settings程序包”部分。iTunes會(huì)備份這個(gè)目錄的內(nèi)容。 |