可以使用NSKeyedArchiver把數(shù)據(jù)保存到本地,在需要使用數(shù)據(jù)的時(shí)候使用NSKeyedUnarchiver來讀取數(shù)據(jù),簡單的數(shù)據(jù)如下
- (void)saveAndReadSimpleData
{
NSArray *array = @[@"1", @"2", @"3"];
[NSKeyedArchiver archiveRootObject:array toFile:[self filePath]];
NSArray *arr = [NSKeyedUnarchiver unarchiveObjectWithFile:[self filePath]];
}
- (NSString *)filePath
{
NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
return [documentPath stringByAppendingPathComponent:@"array.data"];
}```
但是大多數(shù)時(shí)候需要保存的數(shù)據(jù)都是自定義類的實(shí)例,例如我們有一個`Person`類,擁有`name`和`age`兩個屬性
@interface Person : NSObject
@property(nonatomic, copy) NSString *name;
@property(nonatomic, assign) NSInteger age;
@end
在使用上同上
-
(void)saveAndReadCustomData
{
Person *p = [Person new];
p.name = @"JC";
p.age = 88;[NSKeyedArchiver archiveRootObject:p toFile:[self filePath]];
Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:[self filePath]];
}
編譯運(yùn)行的時(shí)候程序會奔潰并伴隨如下的錯誤
`*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Person encodeWithCoder:]: unrecognized selector sent to instance 0x7fe1c872ec20'`
這是因?yàn)槭褂米远x的類進(jìn)行歸檔和解檔的時(shí)候需要實(shí)現(xiàn)協(xié)議`NSCoding`
在`Person.m`文件中實(shí)現(xiàn)`NSCoding`協(xié)議的兩個方法
(instancetype)initWithCoder:(NSCoder *)coder
{
// self = [super initWithCoder:coder];
//這里需要特別注意,調(diào)用的是super的init方法而不是initWithCoder:coder方法
self = [super init];
if (self) {
self.name = [coder decodeObjectForKey:@"name"];
self.age = [coder decodeIntegerForKey:@"age"];
}
return self;
}(void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeInteger:self.age forKey:@"age"];
}
再次運(yùn)行程序,錯誤消失,能正常地進(jìn)行歸檔和解檔
######這里需要特別注意的是在`- (instancetype)initWithCoder:(NSCoder *)coder`方法中,調(diào)用的是`self = [super init];`,而不是`self = [super initWithCoder:coder];`,調(diào)用后面的方法會報(bào)父類沒有相應(yīng)方法的錯誤#####