Cocoa提供了Core Data,他能在后台处理所有文件内容
Cocoa提供了两个通用的文件处理类:属性列表和对象编码
一、属性列表类
在Cocoa中,有一类名为属性列表的对象,简写为plist。
这些列表包含Cocoa操作的一组对象,Cocoa知道如何将他们保存到文件中并进行加载
属性列表类包括:NSArray、NSDictionary、NSString、NSNumber、NSDate和NSData以及他们的变体
1.NSDate
NSDate是Cocoa中用于处理日期和时间的基础类
[NSDate date]获取当前的日期和时间,它是自动释放对象
+dateWithTimeIntervalSinceNow:(NSTimeInterval *)获取与当前时间相隔的时间差
NSTimeInterval是一个双精度参数,表示以秒为单位的时间间隔,正数为将来的时间,负数为过去的时间
举例代码:
NSDate *yesterday = [NSDate dateWithTimeIntervalSinceNow: -(24 * 60 * 60)];
2.NSData
NSData类包含大量字节,可以获得数据的长度和指向字节起始位置的指针
NSData是一个对象,适用于常规的内存管理行为,可以写成自动释放对象
NSData是不可改变的,被创建后就不能改变,可以使用但不能更改其中内容
NSMutableData支持在数据内容中添加和删除字节
举例代码:
NSData *data =[NSData dataWithBytes:string
length:strlen(string)+1];
3.写入和读取属性列表
(1)写入
集合属性列表类(NSArray、NSDictionary)具有一个-writeToFile:atomically;方法用于将属性列表写入文件
NSString和NSData也具有writeToFile:atomically方法,但只能写出字符串或数据块,所以可以写入数组然后再保存数组
举例代码:
NSArray *phrase;
phrase = [NSArray arrayWithObjects:@"I",@"AM",@"DE",@"WEI",@"I'M ",@"29",@"YEARS",@"OLD",nil];
[phrase writeToFile:@"/tmp/xxxxx.plist" atomically:YES];
Tip:atomically为YES时保存过程中会占用双倍的硬盘空间来保存文件
有些plist文件是以二进制压缩保存的,可以使用plutil -convert xml1 filename.plist转换一下再阅读
(2)读取
使用-arrayWithContentsOfFile方法读取文件(因为只能用数组保存所以返回的也会是数组)
举例代码:
NSArray *phrase = [NSArray arrayWithContentsOfFile:@"tmp/xxx.plist"];
NSLog(@"%@",phrase);
(3)最简单的保存可使用NSData的writeToFile:atomically转换
不过这个方法不返回任何错误信息,如果不能加载文件只能得到nil指针,不能确定出现了何种错误
二、编码对象
将对象自身的实例变量和其他数据编码为数据块保存到磁盘,或者将数据块度回到内存并基于数据创建新对象,称为序列化和反序列化 等价于 编码和解码
对于任何Objective-C都是用encodeObject:forKey;进行编码
恢复某个对象,可以使用decodeSomethingForKey方法
如果对象不是属性列表类型,则采用NSCoding协议和实现方法来编码和解码对象
采用NSCoding协议意味着必须实现encodeWithCoder和initWithCoder方法
举例代码:
#import <Foundation/Foundation.h>
@interface Thingie : NSObject <NSCoding> {
NSString *name;
int magicNumber;
float shoeSize;
NSMutableArray *subThingies;
}
@property (copy) NSString *name;
@property intmagicNumber;
@property float shoeSize;
@property (retain) NSMutableArray *subThingies;
- (id)initWithName: (NSString *) n
magicNumber: (int) mn
shoeSize: (float) ss;
@end // Thingie
@implementationThingie
@synthesize name;
@synthesizemagicNumber;
@synthesize shoeSize;
@synthesizesubThingies;
- (id)initWithName: (NSString *) n
magicNumber: (int) mn
shoeSize: (float) ss {
if (self = [super init]) {
self.name = n;
self.magicNumber = mn;
self.shoeSize = ss;
self.subThingies = [NSMutableArray array];
}
return (self);
}
- (void) dealloc {
[name release];
[subThingies release];
[super dealloc];
} // dealloc
- (void) encodeWithCoder: (NSCoder *) coder {
[coder encodeObject: name
forKey: @"name"];
[coder encodeInt: magicNumber
forKey: @"magicNumber"];
[coder encodeFloat: shoeSize
forKey: @"shoeSize"];
[coder encodeObject: subThingies
forKey: @"subThingies"];
} // encodeWithCoder
- (id) initWithCoder: (NSCoder *) decoder {
if (self = [super init]) {
self.name = [decoder decodeObjectForKey: @"name"];
self.magicNumber = [decoder decodeIntForKey: @"magicNumber"];
self.shoeSize = [decoder decodeFloatForKey: @"shoeSize"];
self.subThingies = [decoder decodeObjectForKey: @"subThingies"];
}
return (self);
} // initWithCoder
- (NSString *) description {
NSString*description =
[NSString stringWithFormat: @"%@: %d/%.1f %@",
name, magicNumber, shoeSize, subThingies];
return(description);
} // description
@end // Thingie
使用NSKeyArchiver把对象归档到NSData中,
keyedArchiver使用键/值对保存对象的信息
archivedDataWithRootObject方法,先在后台创建一个NSKeyedArchiver实例,然后将实例传递给-encodeWithCoder
方法,方法复制自身属性时,可以对其他对象也进行编码