Chapter 12 : 归档
1. 归档 :
-> 定义: 用某种格式来保存一个或多个对象,以便以后还原这些对象的过程。其中包括将多个对象写入文件,以便以后读回该对象。
-> 方法:
(1)属性列表;
(2)带键值的编码。
2. 属性列表:若对象是NSString, NSDictionary, NSArray, NSData, NSNumber对象时,可以使用writeToFile:atomically:方法将数据写入到文件中,
是以属性列表的形式写到文件中的。
PS : 参数atomically为YES, 表示先将数据写到临时备份文件中,一旦成功,再转移到文件中。
示例代码:
#import <Foundation/Foundation.h> int main(int argc, char *argv[]) { NSAutoreleasePool *pool = [[NSAutorelease alloc] init]; NSDictionary *glossary1 = [NSDictionary dictionaryWithObjectsAndKeys: @"A class defined so other classes can inherit", @"abstract class", @"To implement all the method defined in a protocol", @"adopt", @"Storing an object for later use", @"archiving", nil]; if ([glossary writeToFile:@"glossary" atomically:YES] == NO) NSLog(@"Save to file failed!"); NSDictionary *glossary2 = [NSDictionary dictionaryWithContentsOfFile:@"glossary"]; for (NSString *key in [glossary2 allKeys]) { NSLog(@"%@:%@", key, [glossary objectForKey:key]); } [pool drain]; return 0; }
PS : 读回归档数据的各种方法:
-> 读回NSData数据:dataWithContentsOfFile:
-> 读回NSString数据:stringWithContentsOfFile:
-> 读回属性列表数据:dictionaryWithContentsOfFile:或者arrayWithContentOfFile:
3. 带键值的编码:
-> NSKeyedArchiver类 : 使用NSKeyedArchiver类创建带键的档案,在带键的档案中,每个归档的字段都有一个名称。
-> 归档某个对象的时候,会为他提供一个名称,即键。
-> 从归档中检索对象时,是根据键来检索的,所以对象的写入归档可按做任意顺序。
-> 如果向类添加新的实例变量或删除实例变量,程序也可以进行处理。
NSKeyedArchiver类中的archiveRootObject:toFile:方法将数据对象存储到磁盘上,如:
NSDictionary *glossary = [...]; [NSKeyedArchiver archiveRootObject:glossary toFile:@"file"];
通过NSKeyedUnarchiver类中的unArchiveObjectWithFile:方法将创建的归档文件读入执行的程序中,如:
NSDictionary *glossary = [NSKeyedUnarchiver unArchiveObjectWithFile:@"file"];
实现NSKeyedArchiver类和NSKeyedUnarchiver类操作的类必须遵守<NSCoding>协议,实现
encodeWithCoder: // 编码方法
initWithCoder: // 解码方法
PS : 对于基本的Objective-C类(NSString, NSArray, NSDictionary, NSSet, NSDate, NSNumber, NSData)则使用
encodeObject:forKey:编码方法和decodeObject:forKey:解码方法:
代码示例:
#import <Foundation/Foundation.h> @interface AddressCard : NSObject <NSCoding, NSCopying> { NSString *name; NSString *email; } @property (copy, nonatomic) NSString *name; @property (copy, nonatomic) NSString *email; - (void)setName:(NSString *)theName andEmail:(NSString *)theEmail; ... @end
// @implementation // 编码方法 - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encoderObject:name forKey:@"AddressCardName"]; [encoder encoderObject:email forKey:@"AddressCardEmail"]; } // 解码方法 - (id)initWithCoder:(NSCoder *)decoder { name = [[decoder decoderObjectForKey:@"AddressCardName"] retain]; email = [[decoder decoderObjectForKey:@"AddressCardEmail"] retain]; } // @end
-> 使用NSData创建自定义档案, 指定要写入归档数据的存储空间,即下面的dataArea.
NSMutableData *dataArea = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:dataArea];
4. 归档实现深复制:需要生成一个对象(或不支持NSCopying协议的对象)的深复制时,使用如下实现复制:
NSMutableArray *dataArray = [...]; NSMutableArray *dataArray2; NSData *data = [NSKeyedArchiver archivedDataWithRootObject:dataArray]; dataArray2 = [NSKeyedUnarchiver unarchivedObjectWithData:data]; // 或 NSMutableArray *dataArray2 = [NSKeyedUnarchiver unarchivedObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:dataArray]];
示例代码: