Objective-C基础教程学习笔记(十五)文件加载与保存

Cocoa提供了两个通用的文件处理类:属性列表和对象编码。

 

属性列表

在Cocoa中,有一类名为属性列表的对象,常简写为plist。这些列表包含Cocoa知道如何操作的一组对象。具体来讲,Cocoa知道如何将它们保存到文件中并进行加载。属性列表类包括NSArray、NSDictionary、NSString、NSNumber、NSDate和NSData,以及它们的变体。

 

NSDate

程序中经常要处理时间和日期。NSDate是Cocoa中用于处理时间和日期的基础类。

可以使用[NSDate date]获取当前的日期和时间,它是一个自动释放对象。

NSDate *date = [NSDate date];

NSLog(@”today is %@”,date);

输出:today is 2012-10-15 10:21:22 -0400

你可以使用一些方法比较两个日期,从而对列表进行排序。还可以获取与当前时间相隔一定时差的日期。例如,你可能需要24小时之前的确切日期:

NSDate *yesterday = [NSDate dateWithTimeIntervalSinceNow:-(24 * 60 * 60)];

NSLog(@”yesterday is %@”,yesterday);

+dateWithTimeIntervalSinceNow:接受一个NSTimeInterval参数,该参数是一个双精度值,表示以秒为单位的时间间隔。通过该参数可以指定时间偏移的方式:对于将来的时间,使用正的时间间隔;对于过去的时间,使用负的时间间隔。

 

NSData

将数据缓冲区传递给函数是C中的常见操作。为此,你通常将缓冲区的指针和长度传递给某个函数。另外,C语言中可能会出现内存管理问题。例如,如果缓冲区已经被动态分配,那么当它不再使用时,由方便负责将其清除?

Cocoa为我们提供了NSData类,该类包装了大量字节。你可以获得数据的长度和指向字节起始位置的指针。因为NSData是一个对象,适用于常规的内存管理行为。因此,如果将数据块传递给一个函数或方法,可以通过传递一个自动释放NSData来实现,无需担心内存清除问题。下面的NSData对象将保存一个普通的C字符串,然后输出数据:

const char *string = “Hi there ,this is a C string!”;

NSData *data = [NSData dataWithBytes:string length:strlen(string) +1];

NSLog(@”data is %@”,data);

NSLog(@”%d byte string is ‘%s’”,[data length],[data bytes]);

NSData对象是不可变的。它们被创建后就不能改变。可以使用它们,但是不能更改其中的内容。但是,NSMutableData支持在数据内容中添加和删除字节。

 

写入和读取属性列表

集合属性列表类(NSArray、NSDictionary)具有一个-writeToFile:atomically:方法,用于将属性列表写入文件。NSString和NSData也具有writeToFile:atomically:方法,但它只能写出字符串或数据块。

因此,我们可以将字符串存入一个数组,然后保存该数组:

NSArray *phrase;

phrase = [NSArray arrayWithObjects:@”I”,@”seem”,@”to”,@”be”,@”a”,@”verb”,nil];

[phrase writeToFiel:@”/tmp/verbiage.txt” atomically:YES];

现在看一下文件/tmp/veribiage.txt,应该看到如下代码:

<?xml version=”1.0” encoding=”UTF-8”?>

<!DOCTYPE plist PUBLIC “-//Apple/DTD PLIST 1.0//EN”

http://www.apple.com/DTDs/PropertyList-1.0.dtd”>

<plist version=“1.0》

<array>

<string>I</string>

<string>seem</string>

<string>to</string>

<string>be</string>

<string>a</string>

<string>verb</string>

</array>

</plist>

现在已将verbiage.txt文件存放在磁盘上,可以使用+arrayWithContentOfFile:方法读取该文件。代码如下所示:

NSArray *phrase2 = [NSArray arrayWithContentOfFile:@”/tmp/verbiage.txt”];

NSLog(“@”%@”,phrase2);

 

writeToFile:方法中的atomically。这个参数的值为BOOL类型,用于通知Cocoa是否应该首先将文件内容保存在临时文件中,当文件成功保存后,再将临时文件和原始文件交换。这是一种安全机制:如果在保存过程中出现意外,不会破坏原始文件。但是这种安全机制需要付出一定的代码:在保存过程中,由于原始文件仍然保存在磁盘中,所以需要使用双倍的磁盘空间。除非保存的文件非常大,将会占用用户硬盘的空间,否则应该自动保存文件。

如果能将数据精简为属性列表类型,则可以使用这些非常便捷的调用 来将内容保存到磁盘中,供以后读取。如果你正在从事一项新创意或设计一个新项目,可以使用这些便捷方法来快速编写和运行程序。即使只想把数据块保存在磁盘中,并且根本不需要使用对象,也可以使用NSData来简化工作。只需将数据包装在一个NSData对象中,然后在NSData对象上调用writeToFile:atomically:.

这些函数的一个缺点是,它们不会返回任何错误信息。如果不能加载文件,只能从方法中得到nil指针,而不能确定出现了何种错误。

 

编码对象

遗憾的是,无法总是将对象信息表示为属性列表类。如果能将所有对象都表示为数组字典,我们就没有必要使用自己的类了。所幸,Cocoa具备一种机制来将对象自身转换为某种格式并保存到磁盘中。对象可以将它们的实例变量和其它数据编码为数据块,然后保存到磁盘中。以后将这些数据块读回到内存中,并且还能基于保存的数据创建新对象。这个过程称为编码和解码,或称为序列化和反序列化。

posted @ 2012-10-15 10:48  TQ.CH  阅读(583)  评论(0编辑  收藏  举报