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]];

 

示例代码:

 

 

 

posted on 2012-09-28 17:48  BankFish  阅读(495)  评论(0编辑  收藏  举报