目錄[-]
一、瞭解NSUserDefaults以及它可以直接存儲的類型
NSUserDefaults是一個單例,在整個程序中只有一個實例對象,他可以用於數據的永久保存,而且簡單實用,這是它可以讓數據自由傳遞的一個前提,也是大家喜歡用它保存簡單數據的一個主要原因。
使用 NSUserDefaults 存儲自定義對象的最初,我們必須認識NSUserDefaults可以存儲哪一些類型的數據,下面一一列出:
NSUserDefaults支持的數據類型有:NSNumber(NSInteger、float、double),NSString,NSDate,NSArray,NSDictionary,BOOL.
如果想要將上述數據類型的數據永久保存到NSUserDefaults中去,只需要簡單的操作(一個Value 一個Key ),例如,想要保存一個NSString的對象,代碼實現爲:
1
2
3
4
|
//將NSString 對象存儲到 NSUserDefaults 中 NSString *passWord = @ "1234567" ; NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; [user setObject:passWord forKey:@ "userPassWord" ]; |
將數據取出也很簡單,只需要取出key 對應的值就好了,代碼如下:
1
2
|
NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; NSString *passWord = [ user objectForKey:@ "userPassWord" ]; |
注意:對相同的Key賦值約等於一次覆蓋,要保證每一個Key的唯一性
值得注意的是:
NSUserDefaults 存儲的對象全是不可變的(這一點非常關鍵,弄錯的話程序會出bug),例如,如果我想要存儲一個 NSMutableArray 對象,我必須先創建一個不可變數組(NSArray)再將它存入NSUserDefaults中去,代碼如下:
1
2
3
4
5
|
NSMutableArray *mutableArray = [NSMutableArray arrayWithObjects:@ "123" ,@ "234" , nil]; NSArray * array = [NSArray arrayWithArray:mutableArray]; NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; [user setObject:array forKey:@ "記住存放的一定是不可變的" ]; |
取出數據是一樣的,想要用NSUserDefaults中的數據給可變數組賦值
先給出一個錯誤的寫法:
1
2
3
4
5
|
/*-------------------------錯誤的賦值方法-------------------*/ NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; //這樣寫後,mutableArray 就變成了不可變數組了,如果你要在數組中添加或刪除數據就會出現bug NSMutableArray *mutableArray = [user objectForKey:@ "記住存放的一定是不可變的" ]; |
正確的寫法:
1
2
3
4
5
|
/*-------------------------正確的賦值方法-------------------*/ NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; //可以用alloc 方法代替 NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:[user objectForKey:@ "記住存放的一定是不可變的" ]]; |
二、使用 NSUserDefaults 存儲自定義對象
1、將自定義類型轉換爲NSData類型
當數據重複而且多的時候(例如想存儲全班同學的學號,姓名,性別(這個數據量可能太大了 )),如果不用SQLite 存儲 (多數據最好還是用這個),你可以選擇使用歸檔,再將文件寫入本地,但是這種方式和 NSUserDefaults 比起來麻煩多了(因爲NSFileManage 本來就挺複雜) ,但是問題是,NSUserDefaults 本身不支持自定義對象的存儲,不過它支持NSData的類型,下面舉一個例子來介紹。
我們先建立一個叫Student 的類,這個類裏有三個屬性(學號,姓名,性別),如圖:
我們要做的就是將Student類型變成NSData類型 ,那麼就必須實現歸檔:
這裏要實現 在.h 文件中申明 NSCoding 協議,再 在 .m 中實現 encodeWithCoder 方法 和
initWithCoder 方法就可以了 :
.h 中修改文件如圖 :
.m中加入代碼 :
這樣做就可以將自定義類型轉變爲NSData類型了
2、將自定義類型數據存入 NSUserDefaults 中
如果要存儲全班同學的信息,我們可以建一個NSMutableArray 來存放全班同學的信息(裏面存儲的全是NSData對象)在需要存儲的地方加入代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
//首先,要建立一個可變數組來存儲 NSDate對象 Student *student = [[Student alloc] ini]; //下面進行的是對student對象的 name , studentNumber ,sex 的賦值 student.name = @ "lady-奕奕" ; student.studentNumber = @ "3100104006" ; student.sex = @ "女" ; //這是一個存放全班同學的數組 NSMutableArray * dataArray = [NSMutableArray arrayWithCapacity:50]; //將student類型變爲NSData類型 NSData *data = [NSKeyedArchiver archivedDataWithRootObject:student]; //存放數據的數組將data加入進去 [dataArray addObject:data]; |
如果你只想存一個人的信息,你可以直接將NSData存入NSUserDefaults中 :
1
2
3
4
|
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:student]; NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; [user setObject:data forKey:@ "oneStudent" ]; |
如果你想存儲全班同學的信息,你還要用一個for循環將data 放入 dataArray中,這裏具體的操作就不實現了,只給出存放的代碼:
1
2
3
4
5
|
//記住要轉換成不可變數組類型 NSArray * array = [NSArray arrayWithArray:dataArray]; NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; [user setObject:array forKey:@ "allStudent" ]; |
從NSUserDefaults中取出數據在還原也很簡單
例如還原一個學生的數據:
1
2
3
4
5
|
NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; NSdData *data = [user objectForKey:@ "oneStudent" ]; Student *student = [NSKeyedUnarchiver unarchiveObjectWithData:data]; |
總之,NSUserDefaults 在我們編寫代碼中是最常用的一個永久保存數據的方法,也是最簡單的。
使用NSUserDefaults保存自定義對象
自定義對象:
.h文件
- #import <Foundation/Foundation.h>
- @interface MyObject : NSObject
- {
- NSNumber* lowValue;
- NSNumber* highValue;
- NSString* titleString;
- }
- @property(nonatomic, retain)NSNumber* lowValue;
- @property(nonatomic, retain)NSNumber* highValue;
- @property(nonatomic, retain)NSString* titleString;
- @end
.m文件:
- #import "MyObject.h"
- @implementation MyObject
- @synthesize lowValue, highValue, titleString;
- - (void)encodeWithCoder:(NSCoder *)encoder
- {
- [encoder encodeObject:self.lowValue forKey:@"lowValue"];
- [encoder encodeObject:self.highValue forKey:@"highValue"];
- [encoder encodeObject:self.titleString forKey:@"titleString"];
- }
- - (id)initWithCoder:(NSCoder *)decoder
- {
- if(self = [super init])
- {
- self.lowValue = [decoder decodeObjectForKey:@"lowValue"];
- self.highValue = [decoder decodeObjectForKey:@"highValue"];
- self.titleString = [decoder decodeObjectForKey:@"titleString"];
- }
- return self;
- }
- @end
保存單個MyObject方法:
- - (void)saveCustomObject:(MyObject *)obj
- {
- NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:obj];
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- [defaults setObject:myEncodedObject forKey:@"myEncodedObjectKey"];
- }
- - (MyObject *)loadCustomObjectWithKey:(NSString *)key
- {
- NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
- NSData *myEncodedObject = [defaults objectForKey:key];
- MyObject *obj = (MyObject *)[NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject];
- return obj;
- }
- 保存:
- MyObject* testObj = [[MyObject alloc] init];
- testObj.lowValue =[NSNumber numberWithFloat:122.2 ];
- testObj.highValue = [NSNumber numberWithFloat:19888 ];
- testObj.titleString = @“baoyu”;
- 讀取:
- MyObject* obj = [self loadCustomObjectWithKey:@"myEncodedObjectKey"];
- NSLog(@"%f, %f, %@", [obj.lowValue floatValue], [obj.highValue floatValue], obj.titleString);
保存多個MyObject方法:
- 保存:
- NSMutableArray* array = [[NSMutableArray alloc] init];
- for(int i=0; i<3; i++)
- {
- MyObject* testObj = [[MyObject alloc] init];
- testObj.lowValue =[NSNumber numberWithFloat:122.2+i ];
- testObj.highValue = [NSNumber numberWithFloat:19888+i ];
- testObj.titleString = [NSString stringWithFormat:@"BAOYU%d", i];
- [array addObject:testObj];
- }
- [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:array] forKey:@"myarray"];
- 讀取:
- NSData* data = [[NSUserDefaults standardUserDefaults] objectForKey:@"myarray"];
- NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
- for(MyObject* obj in oldSavedArray)
- {
- NSLog(@"%f, %f, %@", [obj.lowValue floatValue], [obj.highValue floatValue], obj.titleString);
- }