ios開發(fā)常用的五種數(shù)據(jù)存儲方式:
- plist
- NSUserDefaults
- NSKeyedArchiver
- FMDB
- CoreData
這篇文章我們主要回顧NSKeyedArchiver
的使用
NSKeyedArchiver、NSKeyedUnarchiver
1.數(shù)據(jù)從內(nèi)存存儲到閃存上,這個過程稱為歸檔,是將數(shù)據(jù)持久化的一種方式.
2.想要歸檔的數(shù)據(jù)對象,需要遵守NSCoding
協(xié)議娶耍,并且該對象對應(yīng)的類必須提供encodeWithCoder:
和initWithCoder:
方法.
3.歸檔的缺點:歸檔的形式來保存數(shù)據(jù)扯旷,只能一次性歸檔保存以及一次性解壓,所以只能針對小量數(shù)據(jù)堆缘,而且對數(shù)據(jù)操作比較笨拙,即如果想改動數(shù)據(jù)的某一小部分送膳,還是需要解壓整個數(shù)據(jù)或者歸檔整個數(shù)據(jù)
4.序列化與反序列化:將一個Objective-C對象轉(zhuǎn)換成NSData
的操作叫做對象的序列化
;而將一個NSData轉(zhuǎn)換成Objective-C
對象的操作叫做對象的反序列化
. 一個Objective-C對象需要通過實現(xiàn)NSCoding
協(xié)議以便支持序列化與反序列化.
下面我們根據(jù)之前介紹的plist以及NSUserDefault來繼續(xù)完善我們的demo(DataStorageDemo)
1.想要歸檔丑蛤,就需要遵守NSCoding
協(xié)議
我們做用戶登錄的時候需要存儲用戶信息叠聋,我們給它兩個參數(shù):用戶名與密碼
#import <Foundation/Foundation.h>
//要實現(xiàn)對數(shù)據(jù)模型的歸檔,需要我們實現(xiàn)NScoding協(xié)議受裹,NScoping(copy協(xié)議是為了模型數(shù)據(jù)可以復制碌补,對于歸檔而言,不是必須要實現(xiàn))
@interface User : NSObject<NSCoding,NSCopying>
@property (nonatomic, strong) NSString *userName;
@property (nonatomic, strong) NSString *userPassWord;
@end
并且該對象對應(yīng)的類必須提供encodeWithCoder:和initWithCoder:方法
- (void) encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.userName forKey:kUserName];
[aCoder encodeObject:self.userPassWord forKey:kUserPassWord];
}
- (id) initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init]) {
self.userName = [aDecoder decodeObjectForKey:kUserName];
self.userPassWord = [aDecoder decodeObjectForKey:kUserPassWord];
}
return self;
}
如果你想復制數(shù)據(jù)模型棉饶,還需要實現(xiàn)-(id)copyWithZone:(NSZone *)zone
-(id)copyWithZone:(NSZone *)zone
{
User *user = [[self class]allocWithZone:zone];
user.userName = [self.userName copyWithZone:zone];
user.userPassWord = [self.userPassWord copyWithZone:zone];
return user;
}
2. 存:
你可以直接存儲對象
//存儲用戶信息
User *user = [[User alloc]init];
user.userName = self.countNameTextfield.text;
user.userPassWord = self.passwordTextfield.text;
[NSKeyedArchiver archiveRootObject:user toFile:[self getFilePath]];
也可以序列化后(轉(zhuǎn)成NSData)再寫入
//存儲用戶信息
User *user = [[User alloc]init];
user.userName = self.countNameTextfield.text;
user.userPassWord = self.passwordTextfield.text;
NSMutableData *data = [[NSMutableData alloc]init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
[archiver encodeObject:user forKey:@"user"];
[archiver finishEncoding];
NSLog(@"存儲路徑:%@",[self getFilePath]);
[data writeToFile:[self getFilePath] atomically:YES];
路徑:
-(NSString *)getFilePath
{
return [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0] stringByAppendingPathComponent:@"User"];
}
3. 认谜隆:
你可以直接讀取存儲的對象
if ([[NSFileManager defaultManager]fileExistsAtPath:[self getFilePath]]) {
User *user = [NSKeyedUnarchiver unarchiveObjectWithFile:[self getFilePath]];
NSLog(@"%@---%@",self.user.userName,self.user.userPassWord);
}
相應(yīng)的,如果你序列化了這個對象(NSData)照藻,你就需要反序列化進行讀數(shù)
if ([[NSFileManager defaultManager]fileExistsAtPath:[self getFilePath]]) {
NSData *data = [[NSData alloc]initWithContentsOfFile:[self getFilePath]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];
User *user = [unarchiver decodeObjectForKey:@"user"];
[unarchiver finishDecoding];
NSLog(@"%@---%@",user.userName,user.userPassword);
}
4. 刪
刪除很簡單
if ([defaultFileManager fileExistsAtPath:[self getFilePath]]) {
[defaultFileManager removeItemAtPath:[self getFilePath] error:nil];
}
5. NSUserDefaults存儲自定義類
之所以在這里講解這個知識點袜啃,是因為NSUserDefaults只能存儲簡單數(shù)據(jù)類型,如一個User對象幸缕,需要遵循NSCoding協(xié)議序列化成NSData之后才能使用NSUserDefaults存儲
(1). 存
User *user = [[User alloc]init];
user.userName = @"123456";
user.userPassword = @"123456";
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:user];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:data forKey:@"user"];
(2). 取
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSdData *data = [defaults objectForKey:@"user"];
User *user = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSLog(@"%@---%@",user.userName,user.userPassword);