数据持久化
沙盒:
每个应用程序都有一个/Documents文件夹并且应用程序只能读写该文件夹下的文件。
获取/Douments目录:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
常量NSDocumentDirectory表明我们在查找Documents目录的路径。常量NSUserDomainMask表明我们希望将搜索限制于我们的应用程序沙盒。
属性列表序列化:
序列化对象已被转换为字节流,以便存储到文件中或通过网络进行传输。
关于plist文件:要把数据写入文件实现数据持久化,会将文件保存在“沙盒”中,每个应用程序都有一个沙盒,这个沙盒只有自己可以访问,写文件都保存在/Documents文件夹下。且在把文件写入沙盒的时候,数据类型只能是一下几种类型:
NSArray;
NSMutableArray;
NSDictionary;
NSNumber;
NSString;
NSMutableString;
NSData;
其他的自定义对象不能直接写入plist文件,只能先将其序列化,才能在做写文件操作。
其他自定义类型的对象必须先对其进行对象序列化之后,才能将其写入文件,操作步骤如下:
- 先在要进行序列化的类中实现NSCoding协议,并重写其中的两个方法:
- (void)encodeWithCoder:(NSCoder *)aCoder;
- (id)initWithCoder:(NSCoder *)aDecoder;
并且要在这两个方法中对对象中的所有属性进行编码和解码具体实现如下:
President.h
#import <Foundation/Foundation.h>
@interface President : NSObject <NSCoding>
{
NSString *_name;
NSString *_fromYear;
NSString *_toYear;
NSString *_party;
int _age;
}
@property (nonatomic,retain) NSString *name;
@property (nonatomic,retain) NSString *fromYear;
@property (nonatomic,retain) NSString *toYear;
@property (nonatomic,retain) NSString *party;
@property (nonatomic,assign) int age;
@end
President.m
#import "President.h"
#define kNameKey @"Name"
#define kFromYearKey @"FromYear"
#define kToYearKey @"ToYear"
#define kPartyKey @"Party"
#define kAgeKey @"Age"
@implementation President
@synthesize name = _name;
@synthesize fromYear = _fromYear;
@synthesize toYear = _toYear;
@synthesize party = _party;
@synthesize age = _age;
//encode 编码 Decode解码
//对象序列化到本地的方法
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:_nameforKey:kNameKey];
[aCoder encodeObject:_fromYearforKey:kFromYearKey];
[aCoder encodeObject:_toYearforKey:kToYearKey];
[aCoder encodeObject:_partyforKey:kPartyKey];
[aCoder encodeInt:_age forKey:kAgeKey];
}
//反序列化为对象的方法
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init])
{
self.name = [aDecoder decodeObjectForKey:kNameKey];
self.fromYear = [aDecoder decodeObjectForKey:kFromYearKey];
self.toYear = [aDecoder decodeObjectForKey:kToYearKey];
self.party = [aDecoder decodeObjectForKey:kPartyKey];
self.age = [aDecoder decodeIntForKey:kAgeKey];
}
returnself;
}
- (void)dealloc
{
[_name release];
[_fromYearrelease];
[_toYear release];
[_party release];
[super dealloc];
}
- (NSString *)description
{
return [NSStringstringWithFormat:@"<Prisend name:%@ fromYear:%@ toYear:%@ party:%@>",self.name,self.fromYear,self.toYear,self.party];
}
@end
- 在相应的方法中将其写入文件:
- (void)viewDidLoad
{
[superviewDidLoad];
//首先实例化这个对象
President *bush = [[President alloc] init];
bush.name = @"Bush";
bush.fromYear = @"1990";
bush.toYear = @"1991";
bush.party = @"None";
bush.age = 50;
//获得沙盒路径
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath = [paths objectAtIndex:0];
NSString *filePath = [documentPath stringByAppendingPathComponent:@"a.plist"];
//将对象存入数组
NSArray *array = [NSArray arrayWithObjects:bush,bush,bush,bush,bush,bush,bush,bush,bush,bush,bush,bush,bush,nil];
[bush release];
//通过 NSKeyedArchiver 类将对象写入文件
NSMutableData *data = [[NSMutableDataalloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiveralloc] initForWritingWithMutableData:data];
//encodeObject 所传的参数对象必须实现nscopying协议
[archiver encodeObject:array forKey:@"Presidents"];
[archiver finishEncoding];
BOOL success = [data writeToFile:filePath atomically:YES];
[archiver release];
[data release];
//从文件中读取对象
NSData *data2 = [[NSData alloc] initWithContentsOfFile:filePath];
//Unarchiver 解压缩
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiveralloc] initForReadingWithData:data2];
NSMutableArray *array2 = [unarchiver decodeObjectForKey:@"Presidents"];
[unarchiver finishDecoding];
[unarchiver release];
[data2 release];
//nslog一个对象,会调用这个对象的description方法,然后把这个方法返回的字符串输出到控制台上。
NSLog(@"____________ %@",array2);
}