使用NSData进行归档

来源:互联网 发布:企业信息化软件需求 编辑:程序博客网 时间:2024/06/06 04:17

先前的博文中  我  提到过  我们  可以采取  encodeObject:forKey:这项措施  对基本的Objective-C物件  和  编写过编码措施及解码措施的物件  进行编码。如果  某类物件中的每一个  都包含  一些基本的数据类型,比如  整数类型int,浮点类型float,我们  必须知道  如何对他们  进行编码  和  解码。这个  在先前一篇博文中的表格里  已经列举出来了。

我们  创建  一类简单的物件MyClass。下面  是  MyClass这类物件的接口文件。

接下来  是  MyClass这类物件的实施文件:

每个MyClass类型的物件  都包含  stringValue,intValue  和  floatValue这三个变量。从MyClass这类物件的实施文件  可以看出  有  encodeWithCoder:  和  initWithCoder:这两项措施  适用于  MyClass这类物件。

这三行语句  以及
这行语句  生成了  stringValue、setStringValue:,intValue、setIntValue:  和  floatValue、setFloatValue:这六项措施。
在encodeWithCoder:这项措施当中  由于  stringValue这个物件  属于  基础框架中的物件,所以  我们  采取了  encodeObject:ForKey:这项措施  对其  进行了  编码。对于  char,short,long  和  long long这类的基本数据类型  必须先要确定  这些数据的长度。我们  可以调用  sizeof()函数  来确定  这些数据类型的长度。确定了  数据长度过后  再采取  前一篇博文中表格里的措施  对  这些数据  进行编码。
也许  你  并不想采取  archiveRootObject:toFile:这项措施  将  某个物件  直接  写入  文件,而是  将  一些物件  收集  在一起后  再  写入  一个单独的文件。我们  可以利用  objectiv-c当中的数据物件,也就是  NSData这类物件,办到  这点。
之前  我们  提到过  NSData这类物件  可以用来  在内存当中  创建  一个用于存储数据的区域。这样的区域  一般  在数据  写入  文件之前  临时  存储  数据  或者  用来存储  从磁盘中读取出来的数据。创建数据区域的最简单办法  就是  向  NSMutableData这类物件  发送  data这条消息,就像  这样:
在下面的程序当中  我们  将  一个AddressBook类型的物件  和  一个MyClass类型的物件  存入  同一个文件当中:

这个程序中的

这行语句  先为一个NSKeyedArchiver类型的物件  分配了  内存空间,然后  将  dataArea  设定为  归档数据写入的区域。

接着  我们  对archiver这个物件  采取  encodeObject:forKey:这项措施  对需要归档的物件  进行编码,并且  给  每个需要归档的物件  给  一个关键字。最后  我们  对archiver这个物件  采取了  finishEncoding这项措施,被编好码的数据  就存储  到了  dataArea这个数据区域当中。

我们  之所以能够对  objectOfMyClass1这个MyClass类型的物件  采取  encodeObject:forKey:这项措施,是因为  我们  编写了  encodeWithCoder:  和  initWithCoder:这两项措施,并且  使  其  适用于  MyClass这类物件。

对archiver这个物件  采取  finishEncoding这项措施后,就不能再对其他物件  进行编码了。

这时  dataArea这个数据区域  就包含着  编码后需要归档的物件了,我们  可以将这些需要归档的物件  用  这样的形式  写入  文件。

这行语句  对dataArea这个数据区域  采取了  writeToFile:atomically:这项措施  将  dataArea这个区域中的数据  写入  文件myArchive。如果  数据写入  成功了,writeToFile:atomically:这项措施产生的结果  就会是  YES,如果  失败了,这项措施产生的结果  就会是  NO。

要将  归档文件中的数据  读取出来  也很  简单:先创建  一个NSData类型的物件  用作  临时存储数据的区域。接下来  将  归档文件中的数据  读取  到NSData类型的数据区域当中。然后  创建  一个NSKeyedUnarchiver类型的物件,将  这个NSKeyedUnarchiver类型物件读取数据的位置  设定为  刚刚创建的NSData数据区域。最后  我们  对这个NSKeyedUnarchiver类型的物件  采取  decodeObjectForKey:这项措施,对特定关键字所对应的物件  进行解码。解码  完成过后,我们  必须对这个NSKeyedUnarchiver类型物件  采取  finishDecoding这项措施。

下面的程序  示范了  如何完成  刚刚所说的这些步骤:

#import <Foundation/NSObject.h>#import <Foundation/NSAutoreleasePool.h>#import <Foundation/NSString.h>#import <Foundation/NSKeyedArchiver.h>#import <Foundation/NSCoder.h>#import <Foundation/NSData.h>#import "AddressBook.h"#import "MyClass.h"int main(int argc,const char *argv[]){    NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];    NSData *dataArea;    NSKeyedUnarchiver *unarchiver;    AddressBook *myBook;    MyClass *objectOfMyClass;    dataArea=[NSData dataWithContentsOfFile:@"myArchive"];    if(dataArea==nil)    {        NSLog(@"读取归档文件失败");        return 1;    }    unarchiver=[[NSKeyedUnarchiver alloc] initForReadingWithData:dataArea];    myBook=[unarchiver decodeObjectForKey:@"AddressBookMyBook"];    objectOfMyClass=[unarchiver decodeObjectForKey:@"MyClassObject"];    [unarchiver finishDecoding];    [unarchiver release];    [myBook list];    NSLog(@"%@,%i,%g",[objectOfMyClass stringValue],[objectOfMyClass intValue],[objectOfMyClass floatValue]);    [pool release];    return 0;}


运行  这个程序后,可以得到  这样的结果:

从运行的结果  可以看出  AddressBook类型的物件myBook  和  MyClass类型的物件objectOfMyClass  都成功地  存储到了  归档文件当中。


From:http://www.tongwenguan.com/tag/finishencoding