
####簡介:
- NSUserDefaults是一個單例,在整個程序中只有一個實例對象,他可以用于數(shù)據(jù)的永久保存,而且簡單實用,這是它可以讓數(shù)據(jù)自由傳遞的一個前提。
- NSUserDefaults適合 存儲輕量級 的本地數(shù)據(jù) ,比如要保存一個登陸界面的數(shù)據(jù),用戶名、密碼之類的,個人覺得使用NSUserDefaults是首選。下次再登陸的時候就可以直接從NSUserDefaults里面讀取上次登陸的信息。就像讀字符串一樣,直接讀取就可以了。
- 用NSUserDefaults存儲的數(shù)據(jù)下次程序運(yùn)行的時候依然存在 .它的數(shù)據(jù)存儲在應(yīng)用程序內(nèi)置的一個plist文件里, 在/Library/Prefereces沙盒路徑下.
支持?jǐn)?shù)據(jù)格式:
NSNumber ( Integer、Float、Double )
NSString
NSArray
NSDictionary
BOOL類型
NSDate
簡單類型數(shù)據(jù)讀寫 NSUserDefaults 中:
// 1. 創(chuàng)建NSUserDefaults單例:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// 2. 數(shù)據(jù)寫入:
// 通過 key 值 來存入 和 讀取數(shù)據(jù)
[defaults setInteger:23 forKey:@"myInteger"];
// 注意:對相同的Key賦值約等于一次覆蓋,要保證每一個Key的唯一性
// 3. 將數(shù)據(jù) 立即存入到 磁盤:
[defaults synchronize];
// 4. 通過key值 按照寫入對應(yīng)類型 讀取數(shù)據(jù) 有返回值
NSInteger *myInteger = [defaults integerForKey:@"myInteger"];
注意:
NSUserDefaults 存儲的對象全是不可變的(這一點非常關(guān)鍵,弄錯的話程序會出bug),例如,如果我想要存儲一個 NSMutableArray 對象,我必須先創(chuàng)建一個不可變數(shù)組(NSArray)再將它存入NSUserDefaults中去,代碼如下:
NSMutableArray *mutableArray = [NSMutableArray arrayWithObjects:@"123",@"234", nil];
NSArray * array = [NSArray arrayWithArray:mutableArray];
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
[user setObject:array forKey:@"記住存放的一定是不可變的"];
取出數(shù)據(jù)是一樣的,想要用NSUserDefaults中的數(shù)據(jù)給可變數(shù)組賦值, 先給出一個錯誤的寫法:
/*-------------------------錯誤的賦值方法-------------------*/
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
//這樣寫后,mutableArray 就變成了不可變數(shù)組了,如果你要在數(shù)組中添加或刪除數(shù)據(jù)就會出現(xiàn)bug
NSMutableArray *mutableArray = [user objectForKey:@"記住存放的一定是不可變的"];
正確的寫法:
/*-------------------------正確的賦值方法-------------------*/
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
NSMutableArray *mutableArray = [NSMutableArray
arrayWithArray:[user objectForKey:@"記住存放的一定是不可變的"]];
將自定義類型數(shù)據(jù)讀寫 NSUserDefaults 中
使用NSKeyedArchiver 對數(shù)據(jù)進(jìn)行歸檔 反歸檔.
- 將自定義類型轉(zhuǎn)換為NSData類型:
當(dāng)數(shù)據(jù)重復(fù)而且多的時候(例如想存儲全班同學(xué)的學(xué)號,姓名,性別(這個數(shù)據(jù)量可能太大了 )),如果不用SQLite 存儲 (多數(shù)據(jù)最好還是用這個),可以選擇使用歸檔,再將文件寫入本地,但是這種方式和 NSUserDefaults 比起來麻煩多了(因為NSFileManage 本來就挺復(fù)雜) ,但是問題是,NSUserDefaults 本身不支持自定義對象的存儲,不過它支持NSData的類型,可以轉(zhuǎn)化為 NSdata 類型 。
我們先建立一個叫Student 的類,這個類里有三個屬性(姓名, 年齡, 性別),代碼如下:
// Created by LiCheng on 16/5/5.
// Copyright ? 2016年 LiCheng. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface Student : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *sex;
@property (nonatomic, assign) NSInteger age;
@end
我們要做的就是將Student類型變成NSData類型 ,那么就必須實現(xiàn)歸檔:
這里要實現(xiàn) 在.h 文件中申明 NSCoding 協(xié)議,再 在 .m 中實現(xiàn) encodeWithCoder 方法 和
initWithCoder 方法就可以了 :
.h 中修改,代碼如下 :
#import <Foundation/Foundation.h>
@interface Student : NSObject <NSCoding>
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *sex;
@property (nonatomic, assign) NSInteger age;
@end
.m中加入代碼 :
// Created by LiCheng on 16/5/5.
// Copyright ? 2016年 LiCheng. All rights reserved.
//
#import "Student.h"
@implementation Student
// 歸檔
-(void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:self.age forKey:@"age"];
[aCoder encodeObject:self.sex forKey:@"sex"];
}
// 反歸檔
-(instancetype)initWithCoder:(NSCoder *)aDecoder{
self = [super init];
if (self) {
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeObjectForKey:@"age"];
self.sex = [aDecoder decodeObjectForKey:@"sex"];
}
return self;
}
@end
這樣做就可以將自定義類型轉(zhuǎn)變?yōu)镹SData類型了, 下來進(jìn)行 寫入 和 讀取.
- 寫入數(shù)據(jù):
如果要存儲全班同學(xué)的信息,我們可以建一個NSMutableArray 來存放全班同學(xué)的信息(里面存儲的全是NSData對象)在需要存儲的地方加入代碼:
// 首先,要建立一個可變數(shù)組來存儲 NSDate對象
Student *student = [[Student alloc] init];
// 下面進(jìn)行的是對student對象的 name, age, sex 賦值
student.name = @"張三";
student.age = @"20";
student.sex = @"男";
// 將student對象轉(zhuǎn)換成為NSData類型
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:student];
// 保存學(xué)生信息
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
[user setObject:data forKey:@"oneStudent"];
如果你想存儲全班同學(xué)的信息,你還要用一個for循環(huán)將data 放入 dataArray中.
- 讀取數(shù)據(jù):
例如還原一個學(xué)生的數(shù)據(jù):
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
// 讀取data數(shù)據(jù)
NSData *data = [user objectForKey:@"oneStudent"];
// 將data類型轉(zhuǎn)換成student類型
Student *student = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSLog(@"%@", student.name);
NSLog(@"%@", student.age);
NSLog(@"%@", student.sex);
總之,NSUserDefaults 在我們編寫代碼中是最常用的一個永久保存數(shù)據(jù)的方法,也是最簡單的。
GitHub: https://github.com/LiCheng244/LCUtils
個人博客: http://www.licheng244.com/