简介
归档(Archive)也称为序列化(serialization),把对象转化为字节码,以文件的形式存储在磁盘上,只要遵循了NSCoding协议的对象都可以实现归档和解档(大部分foundation和Cocoa Touch类都可以),将文档上的字节码转化为对象的过程叫做解档(unarchive)也叫反序列化(unserialization)
归档的数据类型要求; NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary五种类型,如果不能归档,我们可以尝试转化为这五种中的任何一种再进行存储
单个对象归档解档
//获取归档文件路径
NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
NSString *filePath = [documentPath stringByAppendingPathComponent:@"test"];
//对字符串@”test”进行归档,写入到filePath中
[NSKeyedArchiver archiveRootObject:@"test" toFile:filePath];
//根据保存数据的路径filePath解档数据
NSString *result = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
//log结构为@”test”,就是上面归档的数据
NSLog(@"%@",result);
归档基本数据或基本对象, 框架内定义的(或者已经遵守NSCoding协议的自定义类)中的单个对象进行归档解档(一次只能归档一个,多个需要分开多次归档)
多个对象归档解档
//获取归档路径
NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
NSString *filePath = [documentPath stringByAppendingPathComponent:@"test"];
//用来承载数据的NSMutableData
NSMutableData *data = [[NSMutableData alloc] init];
//归档对象
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
//将要被保存的三个数据
NSString *name = @"jack";
int age = 17;
double height = 1.78;
//运用encodeObject:方法归档数据
[archiver encodeObject:name forKey:@"name"];
[archiver encodeInt:age forKey:@"age"];
[archiver encodeDouble:height forKey:@"height"];
//结束归档
[archiver finishEncoding];
//写入数据(存储数据)
[data writeToFile:filePath atomically:YES];
//NSMutableData用来承载解档出来的数据
NSMutableData *resultData = [[NSMutableData alloc] initWithContentsOfFile:filePath];
//解档对象
NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:resultData];
//分别解档出三个数据
NSString *resultName = [unArchiver decodeObjectForKey:@"name"];
int resultAge = [unArchiver decodeIntForKey:@"age"];
double resultHeight = [unArchiver decodeDoubleForKey:@"height"];
//结束解档
[unArchiver finishDecoding];
//成功打印出结果,说明成功归档解档
NSLog(@"name = %@, age = %d, height = %.2f",resultName,resultAge,resultHeight);
自定义对象的归档解档,
只需要在自定义类里遵循NSSecureCoding(NSCoding iOS 12后删除)协议,而且必须实现归档方法(encodeWithCoder(aCoder:NSCoder))和解档方法(init?(coder aDecoder: NSCoder))
自定义对象遵循和继承NSObject
class Student:NSObject, NSSecureCoding {
var name: String = ""
var teacher: String = ""
var age: Int = 0
var isMale: Bool = false
static var supportsSecureCoding: Bool = true
override init() {super.init() }
func encode(with coder: NSCoder) {
coder.encode(name, forKey: "name")
coder.encode(teacher, forKey: "teacher")
coder.encode(age, forKey: "age")
coder.encode(isMale, forKey: "isMale")
}
required init?(coder: NSCoder) {
self.name = coder.decodeObject(forKey: "name") as! String
self.teacher = coder.decodeObject(forKey: "teacher") as! String
self.age = Int(coder.decodeInt32(forKey: "age"))
self.isMale = coder.decodeBool(forKey: "isMale")
}
}
归档
let archiverPath = NSHomeDirectory() + "/Documents/xiaohongInfo.plist"
private func archiverStudent() {
let xiaohong = Student()
xiaohong.name = "小红"
xiaohong.age = 19
xiaohong.isMale = true
xiaohong.teacher = "Mrs.Yang"
print(archiverPath)
do {
let data = try NSKeyedArchiver.archivedData(withRootObject: xiaohong, requiringSecureCoding: true)
try data.write(to: URL(fileURLWithPath: archiverPath))
} catch (let err) {
print(err)
}
}
解档
private func unarchiverStudent() {
do {
let data = try Data(contentsOf: URL(fileURLWithPath: archiverPath))
let xiaohong = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as! Student
print(xiaohong)
} catch let error {
print(error)
}
}
相关文档:
NSCoderClass Reference //归档和解档抽象类
NSKeyedArchiverClaee Reference //键控归档[单例] 保存
NSKeyedUnarchiverClass Reference // 解档[单例] 读取