“归档”是值另一种形式的序列化,对模型对象进行归档的技术可以轻松将复杂的对象写入文件,然后再从中读取它们,只要在类中实现的每个属性都是基本数据类型(如int或float)或都是符合NSCoding协议的某个类的实例,你就可以对你的对象进行完整归档。
NSCoding协议声明了两个方法:
- (void)encodeWithCoder:(NSCoder *)encoder,是将对象写入到文件中。
- (void)encodeWithCoder:(NSCoder *)encoder {
[super encodeWithCoder:encoder];
[encoder encodeObject:foo forKey:kFooKey];
[encoder encodeObject:bar forKey:kBarKey];
[encoder encodeInt:someInt forKey:kSomeIntKey];
[encoder encodeFloat:someFloat forKey:kSomeFloatKey]
}
- (id)initWithCoder:(NSCoder *)decoder,是将文件中数据读入到对象中。
- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super initWithCoder:decoder]) {
foo = [decoder decodeObjectForKey:kFooKey];
bar = [decoder decodeObjectForKey:kBarKey];
someInt = [decoder decodeIntForKey:kSomeIntKey];
someFloat = [decoder decodeFloatForKey:kAgeKey];
}
return self;
}
NSCopying协议声明了一个方法:
-(id)copyWithZone:(NSZone *)zone ,是将对象复制方法。
可用于复制对象。实现NSCoping与initWithCoder:非常相似。只要创建一个同一类的新实例,然后将该实例的所有属性都设置为与该对象属性相同的值。
//对对象的操作,下面实现归档
对数据对象进行归档和取消归档。
创建一个NSMutableData实例,用于包含编码的数据,然后创建一个NSKeyedArchiver实例,用于将对象归档到此NSMutableData实例中:
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]
initForWritingWithMutableData:data];
创建这2个实例后,我们使用键/值编码来对希望包含在归档中的所有对象进行归档,例如:
[archiver encodeObject:myObject forKey:@"keyValueString"];
Once we’ve encoded all the objects we want to include, we just tell the archiver we’re
finished, and write the NSMutableData instance to the file system:
[archiver finishEncoding];
BOOL success = [data writeToFile:@"/path/to/archive" atomically:YES];
If anything went wrong while writing the file, success will be set to NO . If success is YES ,
the data was successfully written to the specified file. Any objects created from this
archive will be exact copies of the objects that were last written into the file.
To reconstitute objects from the archive, we go through a similar process. We create an
NSData instance from the archive file and create an NSKeyedUnarchiver to decode the
data:
NSData *data = [[NSData alloc] initWithContentsOfFile:path];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]
initForReadingWithData:data];
After that, we read our objects from the unarchiver using the same key that we used to
archive the object:
self.object = [unarchiver decodeObjectForKey:@"keyValueString"];
Finally, we tell the archiver we are finished:
[unarchiver finishDecoding];
If you’re feeling a little overwhelmed by archiving, don’t worry. It’s actually fairly
straightforward. We’re going to retrofit our Persistence application to use archiving, so
you’ll get to see it in action. Once you’ve done it a few times, archiving will become
second nature, as all you’re really doing is storing and retrieving your object’s properties
using key-value coding.