OC8 文件加载与保存

标准C函数库提供了函数调用来创建、读取和写入文件,例如open()、write()、fopen()和fread()。

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

1、属性列表

在Cocoa中,有一类名为属性列表的对象,常简写为plist。这些列表包含Cocoa知道如何操作的一组对象。

Cocoa知道如何将它们保存到文件中并进行加载。

属性列表类包括NSArray、NSDictionary、NSString、NSNumber、NSData和NSDate,以及它们的变体(如果存在)。

1.1、NSDate

NSDate是Cocoa中用于处理日期和时间的基础类。

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

可以使用一些方法比较两个日期,从而对列表进行排序。还可以获取与当前时间相隔一定时差的日期。

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

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

1.2、NSData

将数据缓冲区传递给函数是C中的常见操作。通常配合缓冲区指针和长度一起使用。

Cocoa提供了NSData类,该类包装了大量字节。可以获得数据的长度和指向字节起始位置的指针。因为NSData是一个对象,适用于常规的内存管理行为。

如果将数据块传递给一个函数或方法,可以通过传递一个自动释放NSData来实现,无需担心内存清除问题。

NSData *data=[NSData dataWithBytes: string 

            length: strlen(string) + 1];

length方法给出字节数。bytes方法给出指向字符串起始位置的指针。

[data length];

[data bytes];

NSData对象是不可变的。它们被创建后就不能改变。可以使用它们,但不能更改其中的内容。

NSMutableData支持在数据内容中添加和删除字节

1.3、写入和读取属性列表

集合属性列表类(NSArray、NSDictionary)具有一个 writeToFile: atomically: 方法,用于将属性列表写入文件。

NSString和NSData也具有writeToFile: atomically: 方法,但它只能写出字符串或数据块。

有些属性列表文件(特别是首选项文件)是以压缩的二进制格式存储的。通过使用plutil命令,可以将这些文件转换成可读的形式。

使用+arrayWithContentsOfFile: 方法读取该文件。

NSArray *phrase2=[NSArray arrayWithContentsOfFile: @"/tmp/a.txt"]

writeToFile: 方法中的单词atomically。它是BOOL类型值,用于通知Cocoa是否应该首先将文件内容保存在临时文件中。当文件成功保存后再降临时文件和原始文件交换。

2、编码对象

无法总是将对象信息表示为属性列表类。Cocoa具有一种机制来将对象自身转换为某种格式并保存到磁盘中。对象可以将它们的实例变量和其它数据编码为数据块,然后保存到磁盘中。以后将这些数据块读到内存中。并且还能基于保存的数据创建新对象。这个过程称为编码和解码,或称为序列化和反序列化。

NSCoding协议,包含方法encodeWithCoder和initWithCoder

@protocol NSCoding

- (void) encodeWithCoder: (NSCoder *) aCoder;

- (id) initWithCoder: (NSCoder *) aDecoder;

@end

encodeWithCoder方法作为解码调用;

initWithCoder方法作为编码调用。

这两个方法的参数是 NSCoder 类型,可以调用encodeObject、encodeInt、encodeFloat等。

[coder encodeObject: name forKey: @"name"];

将name编码,作为字典的”name"键的值。

每种类型都有不同的encodeSomething: forKey: 。对于OC对象类型,都可以使用encodeObject: froKey: 。

如果需要回复某个对象,可以使用decodeSomethingForKey: 。

initWithCoder与其它init方法一样,在对对象执行操作之前,需要使用超类对它们进行初始化。

如果父类采用了NSCoding协议,则应该调用[super initWithCoder: decoder];否则,只需要调用[super init]即可。

NSObject不采用NSCoding协议。

原文地址:https://www.cnblogs.com/cjj-ggboy/p/13057457.html