這篇文章主要寫NSKeyArchiver歸檔和NSKeyUnarchiver解檔的實現(xiàn)
最終存儲后的效果圖為:
Demo地址
對應(yīng)的文件是Human.m和ArchiveViewController.m
目的是希望能歸檔解檔自定義對象享扔,需要遵守NSSecureCoding協(xié)議予跌,這部分在上一篇iOS開發(fā)中數(shù)據(jù)持久化(二):NSUserDefault實現(xiàn)數(shù)據(jù)存儲
里面講過秩贰,所以human.m的實現(xiàn)和上一篇中person.m的實現(xiàn)類似说贝,這里直接寫代碼
在human.h中,聲明相應(yīng)的屬性
@interface Human : NSObject<NSSecureCoding>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end
在human.m文件中,實現(xiàn)相應(yīng)的協(xié)議方法
+ (BOOL)supportsSecureCoding {
return YES;
}
//1.編碼方法
- (void)encodeWithCoder:(nonnull NSCoder *)coder {
[coder encodeObject:self.name forKey:@"HumanName"];
[coder encodeInteger:self.age forKey:@"HumanAge"];
}
//2.解碼方法
- (nullable instancetype)initWithCoder:(nonnull NSCoder *)coder {
self = [super init];
if (self) {
self.name = [coder decodeObjectForKey:@"HumanName"];
self.age = [coder decodeIntegerForKey:@"HumanAge"];
}
return self;
}
之后踏拜,創(chuàng)建ArchiveViewController鞋邑,繼承自UIViewController,主要有兩種歸檔腕窥、解檔方法(勉強可以算是兩種)粒没,我們希望將數(shù)據(jù)存儲到兩個不同的文件中
上面的效果圖中data1文件存儲的是第一種方法歸檔后的數(shù)據(jù)
data2文件存儲的是第二種方法歸檔后的數(shù)據(jù)
所以聲明兩個路徑以及歸檔按鈕、解檔按鈕
在ArchiveViewController.h中
聲明相應(yīng)的屬性
@property (nonatomic, strong) UIButton *archiveButton;
@property (nonatomic, strong) UIButton *unarchiveButton;
@property (nonatomic, copy) NSString *path1;
@property (nonatomic, copy) NSString *path2;
在.m文件中簇爆,懶加載以及完成基本的布局
//放置在Cache文件夾下
- (NSString *)path1 {
if (_path1) {
return _path1;
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
_path1 = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Data1"];
NSLog(@"path1 = %@",_path1);
return _path1;
}
//放置在cache文件夾下
- (NSString *)path2 {
if (_path2) {
return _path2;
}
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
_path2 = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"Data2"];
NSLog(@"path2 = %@",_path2);
return _path2;
}
- (UIButton *)archiveButton {
if (_archiveButton) {
return _archiveButton;
}
_archiveButton = [[UIButton alloc] initWithFrame:CGRectZero];
_archiveButton.titleLabel.font = [UIFont systemFontOfSize:18];
[_archiveButton setTitle:@"歸檔" forState:UIControlStateNormal];
[_archiveButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[_archiveButton addTarget:self action:@selector(archiveData) forControlEvents:UIControlEventTouchUpInside];
return _archiveButton;
}
- (UIButton *)unarchiveButton {
if (_unarchiveButton) {
return _unarchiveButton;
}
_unarchiveButton = [[UIButton alloc] initWithFrame:CGRectZero];
_unarchiveButton.titleLabel.font = [UIFont systemFontOfSize:18];
[_unarchiveButton setTitle:@"解檔" forState:UIControlStateNormal];
[_unarchiveButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[_unarchiveButton addTarget:self action:@selector(unarchiveData) forControlEvents:UIControlEventTouchUpInside];
return _unarchiveButton;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.navigationController.navigationBar.translucent = NO;
self.title = @"歸檔解檔實現(xiàn)";
self.view.backgroundColor = [UIColor whiteColor];
[self.view addSubview:self.archiveButton];
[self.archiveButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.view);
make.centerY.equalTo(self.view);
make.width.greaterThanOrEqualTo(@0);
make.height.equalTo(@30);
}];
[self.view addSubview:self.unarchiveButton];
[self.unarchiveButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.centerX.equalTo(self.view);
make.top.equalTo(self.archiveButton.mas_bottom).offset(20);
make.width.greaterThanOrEqualTo(@0);
make.height.equalTo(@30);
}];
}
下面就是歸檔入蛆、解檔的具體實現(xiàn),在archiveData()方法中實現(xiàn)歸檔哨毁,在unarchiveData()方法中實現(xiàn)解檔
這部分也是花費時間最多的部分枫甲,因為我設(shè)備是ios14,看原先的博客都是使用archiveRootObject...tofile就可將對象歸檔到文件中
但是在iOS14中想幻,這個方法已經(jīng)被棄用了
后面只能看蘋果開發(fā)文檔
發(fā)現(xiàn)可以算做兩種方法實現(xiàn)歸檔、解檔
(本質(zhì)都是一樣的脏毯,獲取到歸檔后的NSData數(shù)據(jù)闹究,然后將其寫入相應(yīng)的文件中)
一種是使用類方法實現(xiàn)
一種是使用實例方法實現(xiàn),可以添加對應(yīng)的鍵值
類方法實現(xiàn)歸檔解檔
這個歸檔的路徑使用path1
歸檔相關(guān)的代碼為:
- (void)archiveData {
Human *human = [[Human alloc] init];
human.name = @"落葉兮兮";
human.age = 24;
//第一種方法食店,使用NSKeyArchiver類方法渣淤,將對象轉(zhuǎn)化為NSData价认,然后寫入指定的文件中
NSError *error = nil;
NSData *data1 = [NSKeyedArchiver archivedDataWithRootObject:human requiringSecureCoding:YES error:&error];
if (error) {
NSLog(@"歸檔失敗自娩,失敗的原因是%@",error);
}
BOOL success = [data1 writeToFile:self.path1 atomically:YES];
if (success) {
NSLog(@"寫入成功");
} else {
NSLog(@"寫入失敗");
}
}
運行后,點擊歸檔椒功,就可以看到相應(yīng)的文件存在
對應(yīng)的解檔讀取數(shù)據(jù)的代碼如下:
- (void)unarchiveData {
NSLog(@"開始解檔數(shù)據(jù)");
//使用NSKeyedUnarchiver類方法解析
NSData *data1 = [NSData dataWithContentsOfFile:self.path1];
NSError *error1 = nil;
Human *human1 = [NSKeyedUnarchiver unarchivedObjectOfClass:[Human class] fromData:data1 error:&error1];
if (error1) {
NSLog(@"解檔數(shù)據(jù)失敗,失敗的原因是%@",error1);
} else {
NSLog(@"解檔數(shù)據(jù)成功");
NSLog(@"human name = %@,age = %ld",human1.name,human1.age);
}
}
運行成功动漾,點擊解檔,可以讀取相應(yīng)的內(nèi)容
使用實例方法歸檔和解檔
這個歸檔的路徑使用path2
歸檔的代碼為:
- (void)archiveData {
NSLog(@"開始歸檔數(shù)據(jù)");
Human *human = [[Human alloc] init];
human.name = @"落葉兮兮";
human.age = 24;
//第二種使用NSKeyArchiver的實例方法,編碼時使用相應(yīng)的鍵值旱眯,然后將編碼后的數(shù)據(jù)寫入執(zhí)行的路徑中
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES];
[archiver encodeObject:human forKey:@"Human"];
[archiver finishEncoding];
NSLog(@"NSKeyArchiver編碼的數(shù)據(jù)為%@",archiver.encodedData);
[archiver.encodedData writeToFile:self.path2 atomically:YES];
NSLog(@"歸檔結(jié)束");
}
解檔的代碼為:(注意解檔時的鍵值要和歸檔的鍵值保持一致)
//使用NSKeyedUnarchiver實例方法解析
NSError *error2 = nil;
NSData *data2 = [NSData dataWithContentsOfFile:self.path2];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data2 error:&error2];
Human *human2 = [unarchiver decodeObjectOfClass:[Human class] forKey:@"Human"];
[unarchiver finishDecoding];
if (error2) {
NSLog(@"解檔數(shù)據(jù)失敗,失敗的原因是%@",error2);
} else {
NSLog(@"解檔數(shù)據(jù)成功");
NSLog(@"human name = %@,age = %ld",human2.name,human2.age);
}
運行后删豺,可以查看到相應(yīng)的文件
而且,來年各種功能方法存儲的是一樣的內(nèi)容妈拌,data1文件的大小是243kb蓬蝶,data2文件的大小是244kb,或許就是因為data2存儲時設(shè)置了鍵值“Human”
總結(jié)
最終存儲后的效果圖為:
Demo地址
對應(yīng)的文件是Human.m和ArchiveViewController.m
iOS開發(fā)中數(shù)據(jù)持久化總結(jié)(一);
iOS開發(fā)中數(shù)據(jù)持久化總結(jié)(二):NSUserDefault實現(xiàn)數(shù)據(jù)存儲
ios開發(fā)中數(shù)據(jù)持久化總結(jié)(三):NSKeyArchive歸檔解檔的實現(xiàn)
ios開發(fā)中數(shù)據(jù)持久化總結(jié)(四):使用FMDataBase存儲數(shù)據(jù)