若要将名种类型的对象存储到文件中,而且不仅仅是字符串、数组和字典类型,有一种更灵活的方法,就是利用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;
}
运行测试
自定义类要想支持归档,需要实现<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;
}