归档NSCoding、NSKeyedArchiver

NSCoding、NSKeyedArchiver

一、简介

看了一下NSKeyedArchiver的官方文档:

NSKeyedArchiver, a concrete subclass of NSCoder, provides a way to encode objects (and scalar values) into an architecture-independent format that can be stored in a file. When you archive a set of objects, the class information and instance variables for each object are written to the archive. NSKeyedArchiver’s companion class, NSKeyedUnarchiver, decodes the data in an archive and creates a set of objects equivalent to the original set.

大概意思是说,NSKeyedArchiver继承自NSCoder,可以把对象经过编码(加密)方式存进一个文件中。当你归档某个类的对象时,这个类的信息以及对象的成员变量的信息都会被写进文件里。NSKeyedArchiver通常和NSKeyedUnarchiver搭配使用,一个编码对象到文件里,一个从文件里解码并获取原始对象的数据。

另外,NSKeyedArchiver只能归档遵守了NSCoding协议的对象,数据在经过归档处理会转换成二进制数据,所以安全性要远远高于XML属性列表(plist)。

二、基本使用方法

对于要存储的对象,首先需要遵守NSCoding协议,并实现encodeWithCoder:方法,告诉NSKeyedArchiver要存储什么数据,怎么存储,不然程序运行时会发生错误,存储数据失败;读取信息时也一样,必须要实现initWithCoder:方法,告诉NSKeyedUnarchiver哪些属性需要解析,怎么解析。

2.1 对象遵守NSCoding协议

@interface Student : NSObject <NSCoding>

@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int age;

@end
@implementation Student

- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:_name forKey:@"name"];
    [aCoder encodeInt:_age forKey:@"age"];
    NSLog(@"encode");
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super init]) {
        _name = [aDecoder decodeObjectForKey:@"name"];
        _age = [aDecoder decodeIntForKey:@"age"];
    }
    NSLog(@"decode");
    return self;
}

@end

2.2 存储数据

path = @"~/Desktop/student.data";

- (IBAction)write:(id)sender {

    Student *stu = [[Student alloc] init];
    stu.name = @"Steven";
    stu.age = 18;

    BOOL result = [NSKeyedArchiver archiveRootObject:stu toFile:path];
    if (result) {
        NSLog(@"归档成功");
    }else {
        NSLog(@"归档失败");
    }
}

生成的存储文件不能打开,或者打开也只能看到乱码。

2.3 读取数据

- (IBAction)read:(id)sender { Student *stu = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; NSLog("%@-%d", stu.name, stu.age); }

三、子类

如果父类也遵守了NSCoding协议,则子类的编写方法如下所示:

@interface Undergraduate : Student

@property (nonatomic, copy) NSString *major;

@end


@implementation Undergraduate

- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [super encodeWithCoder:aCoder];
    [aCoder encodeObject:_major forKey:@"major"];
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super initWithCoder:aDecoder]) {
        _major = [aDecoder decodeObjectForKey:@"major"];
    }
    return self;
}

@end

编码、解码的方法和父类一样。

以上。

你可能感兴趣的:(ios,数据存储,归档,NSCoding)