** 前言:**
歸檔是iOS開發(fā)中數據存儲常用的技巧,歸檔可以直接將對象儲存成文件潜慎,把文件讀取成對象。相對于plist或者userdefault形式,歸檔可以存儲的數據類型更加多樣豌拙,并且可以存取自定義對象。對象歸檔的文件是保密的鳖链,在磁盤上無法查看文件中的內容姆蘸,更加安全墩莫。
一芙委、系統(tǒng)對象的歸檔
兩個核心方法
\+ (BOOL)archiveRootObject:(id)rootObject toFile:(NSString *)path;
\+ (nullable id)unarchiveObjectWithFile:(NSString *)path;
使用NSKeyedArichiver進行歸檔、NSKeyedUnarchiver進行接檔狂秦,這種方式會在寫入灌侣、讀出數據之前對數據進行序列化、反序列化操作裂问。
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:
@"xiaoming", @"name",
@15, @"age",
@"1234567", @"studentid",
@"boy", @"sex",nil];
NSArray *array = @[@"數據1",@"數據2",@"數據3",@"數據4"];
NSString *docPath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
NSString *path1 =[docPath stringByAppendingPathComponent:@"person.archiver"];//后綴名可以隨意命名
NSString *path2 =[docPath stringByAppendingPathComponent:@"data.archiver"];
BOOL flag1 = [NSKeyedArchiver archiveRootObject:array toFile:path1];
BOOL flag2 = [NSKeyedArchiver archiveRootObject:dic toFile:path2];
這種方式可以對基本數據類型進行歸檔侧啼,比如字符串,NSNumber堪簿,當然常用的是對NSArray與NSDictionary進行歸檔痊乾。返回值Flag標志著是否歸檔成功,YES為成功椭更,NO為失敗哪审。
解檔:
NSDictionary *dic = [NSKeyedUnarchiver unarchiveObjectWithFile:path1];
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:path2];
二、對多種類型數據進行歸檔
同樣是使用NSKeyedArchiver進行歸檔虑瀑,不同的是同時歸檔多個數據湿滓,這里我們舉例放入了一個CGPoint點、字符串舌狗、整數(當然很多類型都可以的叽奥,例如UIImage、float等等)痛侍,使用encodeXXX方法進行歸檔朝氓,最后通過writeToFile方法寫入文件。
歸檔:寫入數據
// NSKeyedArchiver 可以對多種類型數據進行歸檔
CGPoint point = CGPointMake(10, 20);
NSString *name = @"xiaoMing";
NSInteger age = 10;
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *path = [docPath stringByAppendingPathComponent:@"multiData.arch"];
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archvier = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
// 對多種類型數據歸檔
[archvier encodeCGPoint:point forKey:@"point"];
[archvier encodeObject:name forKey:@"name"];
[archvier encodeInteger:age forKey:@"age"];
[archvier finishEncoding];
[data writeToFile:path atomically:YES];
解檔:從路徑中獲得數據構造NSKeyedUnarchiver實例,使用decodeXXXForKey方法獲得文件中的對象赵哲。
NSMutableData *dataR = [[NSMutableData alloc] initWithContentsOfFile:path];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:dataR];
CGPoint pointR = [unarchiver decodeCGPointForKey:@"point"];
NSString *nameR = [unarchiver decodeObjectForKey:@"name"];
NSInteger ageR = [unarchiver decodeIntegerForKey:@"age"];
[unarchiver finishDecoding];
NSLog(@"%f,%f,%@,%d",pointR.x,pointR.y,nameR,ageR);
三嘹狞、對自定義對象進行歸檔
除了字典和數組,開發(fā)中往往需要自定義一些對象誓竿,也就是MVC中的model層磅网。
那么如何對自定義對象進行存取就顯得重要的多,歸檔是個不錯的好選擇筷屡。
我們有個自定義對象叫做 person涧偷。
person.h
#import <Foundation/Foundation.h>
// 歸檔自定義對象該對象必須實現nscoding 協議
@interface person : NSObject<NSCoding>
@property (nonatomic,copy) NSString *name;
@property (nonatomic,assign) NSInteger age;
@property (nonatomic,assign) double height;
@end
person.m 需要重寫兩個協議方法
-(void)encodeWithCoder:(NSCoder *)aCoder方法:
-(id)initWithCoder:(NSCoder *)aDecoder方法:
#import "person.h"
@implementation person
// 當將一個自定義對象保存到文件的時候就會調用該方法
// 在該方法中說明如何存儲自定義對象的屬性
// 也就說在該方法中說清楚存儲自定義對象的哪些屬性
-(void)encodeWithCoder:(NSCoder *)aCoder
{
NSLog(@"調用了encodeWithCoder:方法");
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeInteger:self.age forKey:@"age"];
[aCoder encodeDouble:self.height forKey:@"height"];
}
// 當從文件中讀取一個對象的時候就會調用該方法
// 在該方法中說明如何讀取保存在文件中的對象
// 也就是說在該方法中說清楚怎么讀取文件中的對象
-(id)initWithCoder:(NSCoder *)aDecoder
{
NSLog(@"調用了initWithCoder:方法");
//注意:在構造方法中需要先初始化父類的方法
if (self=[super init]) {
self.name=[aDecoder decodeObjectForKey:@"name"];
self.age=[aDecoder decodeIntegerForKey:@"age"];
self.height=[aDecoder decodeDoubleForKey:@"height"];
}
return self;
}
@end
對person對象進行歸檔解檔:
- (IBAction)archiveSelfObject:(id)sender {
person *xiaoMu = [[person alloc] init];
xiaoMu.name = @"小木";
xiaoMu.age = 25;
xiaoMu.height = 180;
// 獲取文件路徑
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *path = [docPath stringByAppendingPathComponent:@"person.arch"];
// 保存自定義對象
[NSKeyedArchiver archiveRootObject:xiaoMu toFile:path];
// 解檔
person *person2 = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
NSLog(@"%@,%d,%.1fcm",person2.name,person2.age,person2.height);
}
返回結果:
** 相關 **
iOS 沙盒目錄結構及正確使用