【iOS数据持久化】归档解档(NSKeyedArchiver/ NSKeyedUnarchiver)

简介

归档(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       //  解档[单例]        读取

升级Xcode 11之后踩坑归档解档

你可能感兴趣的:(iOS,移动开发,数据持久化,NSKeyeArchiver,NAkeyUnarchiver)