使用NSKeyedArchiver归档

作者:追风剑情 发布于:2019-3-8 11:37 分类:Objective-C

若要将名种类型的对象存储到文件中,而且不仅仅是字符串、数组和字典类型,有一种更灵活的方法,就是利用NSKeyedArchiver类创建带键(keyed)的档案来完成。

Mac OS X从版本10.2开始支持带键的档案。在此之前,要使用NSArchiver类创建连续的(sequential)归档。连续的归档需要完全按照写入时的顺序读取归档中的数据。

在带键的档案中,每个归档字段都有一个名称。归档某个对象时,会为它提供一个名称,即键。从归档中获取该对象时,是根据这个键来检索它的。这样,可以按照做任意顺序将对象写入归档并进行检索。另外,如果向类中添加了新的实例变量或删除了实例变量,程序也可以进行处理。

示例:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSDictionary *glossary = @{
            @"abstract class": @"A class defined so other classes can inherit from it.",
            @"adopt": @"To implement all the methods defined in a protocol",
            @"archiving": @"Storing an object for later use."
        };
        
        [NSKeyedArchiver archiveRootObject: glossary toFile: @"glossary.archive"];
        
        // 读取归档文件
        NSDictionary *glossary1 = [NSKeyedUnarchiver unarchiveObjectWithFile: @"glossary.archive"];
        
        for (NSString *key in glossary1)
            NSLog(@"%@: %@", key, glossary1[key]);
    }
    return 0;
}

运行测试

111.png

自定义类要想支持归档,需要实现<NSCoding>协议

在带键的档案中编码和解码基本数据类型
编码方法 解码方法
encodeBool:forKey: decodeBool:forKey:
encodeInt:forKey: decodeInt:forKey:
encodeInt32:forKey: decodeInt32:forKey:
encodeInt64:forKey: decodeInt64:forKey:
encodeFloat:forKey: decodeFloat:forKey:
encodeDouble:forKey: decodeDouble:forKey:

示例二:编码方法和解码方法

#import <Foundation/Foundation.h>

@interface Foo : NSObject <NSCoding>
@property (copy, nonatomic) NSString *strVal;
@property int intVal;
@property float floatVal;

-(void) encodeWithCoder: (NSCoder *) encoder;
-(id) initWithCoder: (NSCoder *) decoder;
@end

@implementation Foo
@synthesize strVal, intVal, floatVal;
-(void) encodeWithCoder: (NSCoder *) encoder
{
    //[super encodeWithCoder: encoder];//如果有父类
    // key通常由类名+变量名组成
    [encoder encodeObject: strVal forKey: @"FoostrVal"];
    [encoder encodeInt: intVal forKey: @"FoointVal"];
    [encoder encodeFloat: floatVal forKey: @"FoofloatVal"];
}

-(id) initWithCoder: (NSCoder *) decoder
{
    strVal = [decoder decodeObjectForKey: @"FoostrVal"];
    intVal = [decoder decodeIntForKey: @"FoointVal"];
    floatVal = [decoder decodeFloatForKey: @"FoofloatVal"];
    return self;
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Foo *myFoo1 = [[Foo alloc] init];
        Foo *myFoo2;
        
        myFoo1.strVal = @"This is the string";
        myFoo1.intVal = 12345;
        myFoo1.floatVal = 98.6;
        
        [NSKeyedArchiver archiveRootObject: myFoo1 toFile: @"foo.arch"];
        
        myFoo2 = [NSKeyedUnarchiver unarchiveObjectWithFile: @"foo.arch"];
        
        NSLog(@"\n%@\n%i\n%g", myFoo2.strVal, myFoo2.intVal, myFoo2.floatVal);
    }
    return 0;
}

运行测试
111.png

标签: Objective-C

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号