提到歸檔, 不得不說(shuō)一句iOS數(shù)據(jù)持久化方式:
1.屬性列表(Plist文件) ,NSUserDefaul
2.歸檔 (NSKeyedArchiver)
3.數(shù)據(jù)庫(kù)(SQlite, CoreData, FMDB(第三方))
歸檔: 將復(fù)雜對(duì)象轉(zhuǎn)化為NSData類型數(shù)據(jù) (復(fù)雜 ---> 歸檔 --->NSData-->writeToFile寫(xiě)入文件)
注意: 歸檔是將對(duì)象轉(zhuǎn)化為數(shù)據(jù)字節(jié), 以文件的形式存儲(chǔ)在磁盤(pán)上.
反歸檔: 將NSData類型對(duì)象轉(zhuǎn)化為復(fù)雜對(duì)象(讀取文件--->轉(zhuǎn)化成NSData文件--->反歸檔--->復(fù)雜對(duì)象)
這里介紹對(duì)自定義類的歸檔反歸檔方法
自定義Person類:
注意事項(xiàng): 一個(gè)類要想實(shí)現(xiàn)歸檔反歸檔, 就必須遵循NSCoding協(xié)議, 實(shí)現(xiàn)兩個(gè)方法, 下面詳細(xì)介紹
#import <Foundation/Foundation.h>
@interface Person : NSObject<NSCoding> //* 遵循NSCoding 協(xié)議
//類的屬性
@property (copy, nonatomic) NSString *name;
@property (copy, nonatomic) NSString *gender;
@property (assign, nonatomic) NSInteger age;
//* 遵循協(xié)議后需要實(shí)現(xiàn)的方法
- (void)encodeWithCoder:(NSCoder *)aCoder;
- (instancetype)initWithCoder:(NSCoder *)aDecoder;
@end
#import "Person.h"
@implementation Person
//歸檔(序列化)
//對(duì)Person類對(duì)象進(jìn)行歸檔時(shí), 執(zhí)行此方法
//并對(duì)Person類中想要進(jìn)行歸檔的所有屬性, 進(jìn)行序列化操作
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:_name forKey:@"name"];
[aCoder encodeInteger:_age forKey:@"age"];
[aCoder encodeObject:_gender forKey:@"gender"];
}
//反歸檔(反序列化)
//對(duì)對(duì)Person類對(duì)象進(jìn)行反歸檔時(shí), 執(zhí)行此方法
//并對(duì)Person類中想要進(jìn)行反歸檔的所有屬性, 進(jìn)行反序列化操作
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
_name = [aDecoder decodeObjectForKey:@"name"];
_gender = [aDecoder decodeObjectForKey:@"gender"];
_age = [aDecoder decodeIntegerForKey:@"age"];
}
return self;
}
@end
歸檔過(guò)程
在Controller 里面調(diào)用該歸檔類, 初始化歸檔對(duì)象, 進(jìn)行歸檔反歸檔操作
------- 對(duì)自定義對(duì)象進(jìn)行歸檔和反歸檔 --------
- (void)archive{
Person *per = [Person new];
per.name = @"姓名";
per.age = 10;
per.gender = @"男";
//歸檔
//1. 準(zhǔn)備路徑
NSString *path = NSHomeDirectory();
path = [path stringByAppendingString:@"SingeDog.txt"];
//2. 準(zhǔn)備存儲(chǔ)數(shù)據(jù)的對(duì)象(用可變數(shù)據(jù)類型來(lái)接收)(用來(lái)初始化歸檔工具)
NSMutableData *data = [NSMutableData data];
//3. 創(chuàng)建歸檔對(duì)象
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
//4.開(kāi)始?xì)w檔
[archiver encodeObject:per forKey:@"person"];
//5. 完成歸檔
[archiver finishEncoding];
//6. 寫(xiě)入文件
BOOL result = [data writeToFile:path atomically:YES];
if (result) {
NSLog(@"歸檔成功: %@",path);
}
//反歸檔
//1. 創(chuàng)建對(duì)象, 獲取接檔路徑
NSData *myData = [NSData dataWithContentsOfFile:path];
//2. 創(chuàng)建反歸檔對(duì)象
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:myData];
//3. 反歸檔(創(chuàng)建對(duì)象, 用來(lái)接收反歸檔的結(jié)果)
Person *aper = [Person new];
//key: 必須與歸檔時(shí)相同
aper = [unarchiver decodeObjectForKey:@"person"];
//4. 結(jié)束反歸檔
[unarchiver finishDecoding];
NSLog(@"%@", aper.name);
}```
------- 對(duì)Foundation框架中的對(duì)象進(jìn)行歸檔和反歸檔 --------
oc中的基本NS數(shù)據(jù)都可以直接進(jìn)行歸檔, 反歸檔操作
-
(void)foundationClass{
//歸檔(以數(shù)組為例說(shuō)明)
//1. 創(chuàng)建路徑
NSString *document = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];//2. 拼接一個(gè)文件
NSString *filePath = [document stringByAppendingString:@"/file.plist"];//3. 創(chuàng)建歸檔對(duì)象
NSArray *array = @[@"C", @"OC", @"UI"];//4. 歸檔
//archiveRootObject: 對(duì)基本數(shù)據(jù)類型數(shù)據(jù)進(jìn)行歸檔的方法
BOOL result = [NSKeyedArchiver archiveRootObject:array toFile:filePath];if (result) {
NSLog(@"array歸檔成功:%@", filePath);
}
//5. 不需要結(jié)束
//反歸檔
//1. 創(chuàng)建對(duì)象用來(lái)接收
NSArray *newArray = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
NSLog(@"解檔結(jié)果 = %@", newArray);
}```
------- 對(duì)自定義內(nèi)容進(jìn)行歸檔和反歸檔 --------
- (void)customContent{
//歸檔
//1. 獲取路徑
NSString *custonPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObject];
custonPath = [custonPath stringByAppendingString:@"/customFile"];
//2. 使用Data對(duì)象存放歸檔數(shù)據(jù)
NSMutableData *data = [NSMutableData data];
//3. 創(chuàng)建歸檔對(duì)象
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
//4. 對(duì)自定義內(nèi)容進(jìn)行歸檔
[archiver encodeObject:@"尼古拉斯.趙四" forKey:@"name"];
[archiver encodeObject:@"男" forKey:@"gender"];
[archiver encodeInt:22 forKey:@"age"];
[archiver encodeObject:@[@"AAAA", @"BBBB", @"CCCC"] forKey:@"array"];
//5. 完成歸檔
[archiver finishEncoding];
//6. 寫(xiě)入本地
BOOL result = [data writeToFile:custonPath atomically:YES];
if (result) {
NSLog(@"寫(xiě)入成功: %@", custonPath);
}
//反歸檔:
//1. 讀取文件, 轉(zhuǎn)化成NSData對(duì)象類型
NSData *unarchiverData = [NSData dataWithContentsOfFile:custonPath];
//2. 創(chuàng)建反歸檔對(duì)象
NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:unarchiverData];
//3. 反歸檔(根據(jù)KEY值訪問(wèn))
NSString *str = [unArchiver decodeObjectForKey:@"name"];
NSLog(@"%@", str);
}```