归档和Java中得序列化机制类似,都是将对象以某个格式保存在制定文件中,方便以后再从文件中恢复它们。
Foundation中常用的类如NSDictionary均实现了NSCoding方法,可以直接序列化
自定义的OC对象需要实现NSCoding协议,并实现其中的两个方法:
- (void)encodeWithCoder:(NSCoder *)aCoder
- (id)initWithCoder:(NSCoder *)aDecoder
看例子:
Student.h:
#import <Foundation/Foundation.h>
@interface Student : NSObject <NSCoding>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int age;
- (id)initWithName: (NSString *) name andAge: (int) age;
+ (id)studentWithName: (NSString *)name andAge: (int) age;
@end
Student.m
#import "Student.h"
@implementation Student
- (id)initWithName:(NSString *)name andAge:(int)age {
if (self = [super init]) {
self.name = name;
self.age = age;
}
return self;
}
+ (id)studentWithName:(NSString *)name andAge:(int)age {
Student *student = [[Student alloc] initWithName:name andAge:age];
return student;
}
#pragma mark 归档
- (void)encodeWithCoder:(NSCoder *)aCoder {
// 调用NSCoder的方法归档对象的每一个变量
[aCoder encodeObject:_name forKey: @"name"];
[aCoder encodeInteger:_age forKey: @"age"];
}
#pragma mark 从归档中恢复对象
-(id)initWithCoder:(NSCoder *)aDecoder {
NSString *name = [aDecoder decodeObjectForKey: @"name"];
int age = [aDecoder decodeIntegerForKey: @"age"];
return [Student studentWithName:name andAge:age];
}
-(NSString *)description {
return [NSString stringWithFormat:@"name = %@, age = %i", _name, _age];
}
@end
main.m
#import <Foundation/Foundation.h>
#import "Student.h"
#pragma mark 归档系统已经实现NSCoding协议的对象(如NSDictionary)
void archiver() {
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@"v1", @"k1", @"v2", @"k2", @"v3", @"k3", nil];
[NSKeyedArchiver archiveRootObject:dict toFile: @"/Users/zzqiltw/Desktop/dict.archiver"];// 打开文件后是乱码
NSDictionary *dict2 = [NSKeyedUnarchiver unarchiveObjectWithFile:@"/Users/zzqiltw/Desktop/dict.archiver"];
[dict2 enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSLog(@"%@ -> %@", key, obj);
}];
}
#pragma mark 归档自定义的已经实现NSCoding协议的对象Student
void archiver2() {
Student *student = [Student studentWithName:@"zzq" andAge:22];
[NSKeyedArchiver archiveRootObject:student toFile:@"/Users/zzqiltw/Desktop/student.archiver"];
Student *student2 = [NSKeyedUnarchiver unarchiveObjectWithFile:@"/Users/zzqiltw/Desktop/student.archiver"];
NSLog(@"student2: %@", student2);
}
#pragma mark 多对象归档
void archiver3() {
Student *student = [Student studentWithName:@"zzq" andAge:22];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@"v1", @"k1", @"v2", @"k2", @"v3", @"k3", nil];
// 创建一个NSMutableData用来保存归档数据,多个对象归档完data写入文件
NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:dict forKey:@"myDict"];
[archiver encodeObject:student forKey:@"aStudent"];
[archiver encodeInteger:10 forKey:@"int"];
[archiver finishEncoding];
if ([data writeToFile:@"/Users/zzqiltw/Desktop/Objects.archiver" atomically:YES] == NO) {
NSLog(@"归档失败");
} else {
NSLog(@"归档成功");
}
NSMutableData *newData = [NSMutableData dataWithContentsOfFile:@"/Users/zzqiltw/Desktop/Objects.archiver"];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:newData];
Student *newStudent = [unarchiver decodeObjectForKey:@"aStudent"];
NSInteger a = [unarchiver decodeIntegerForKey:@"int"];
NSDictionary *newDict = [unarchiver decodeObjectForKey:@"myDict"];
NSLog(@"%@", newStudent);
NSLog(@"%@", newDict);
NSLog(@"%zi", a);
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
// archiver();
// archiver2();
archiver3();
}
return 0;
}