1、对象归档
将各种类型的对象存储到文件中,而不仅仅是字符串、数组和字典类型,有一种更灵活的方法:就是利用NSKeyedAarchiver类创建带键(keyed)的归档文件来完成.
归档是指将对象序列化,这样可以轻松将复杂的对象写入文件,然后再从中读取它们, 只要在类中实现的每个属性都是基本数据类型(如int或float),或都是符合NSCoding协议的某个类的实例,你就可以对对象进行完整归档.
实现NSCoding协议
NSCoding是一个可以由你自行实现的协议,通过扩展你的数据类来支持encode和decode功能就可以了.它们的任务是把数据写到数据缓存,最后持久保存到磁盘中.
//NSCoding协议
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:nameforKey:@"name"];
[aCoder encodeInteger:numberforKey:@"number"];
[aCoder encodeObject:arrayforKey:@"array"];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
[aDecoder decodeObjectForKey:@"name"];
[aDecoder decodeIntegerForKey:@"number"];
[aDecoder decodeObjectForKey:@"array"];
}
return self;
}
归档的实例
1、先创建一个person类,其有三个属性:name,age,sex
2、//编码
- (void)encodeWithCoder:(NSCoder *)aCoder
{
//将每个属性进行编码
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:self.age forKey:@"age"];
[aCoder encodeObject:self.sex forKey:@"sex"];
}
3、//解码
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self == [super init]) {
//使用"键"解码获取"值"
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeObjectForKey:@"age"];
self.sex = [aDecoder decodeObjectForKey:@"sex"];
}
returnself;
}
4、//为自己开辟一块空的空间,用zone占位
- (id)copyWithZone:(NSZone *)zone
{
//为类自己开辟一块空的空间,用zone占位
CHPerson *person = [[[self class]allocWithZone:zone] init];
//为类的属性开辟一块空的空间,用zone占位
person.name = [[self.name copyWithZone:zone] autorelease];
person.age = [[self.age copyWithZone:zone] autorelease];
person.sex = [[self.sex copyWithZone:zone] autorelease];
[person release];
return person;
}
//以上在person类.h和.m文件中实现
5、//取到document路径
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
//拼接plist的路径
NSString *plistPath = [documentsPath stringByAppendingPathComponent:fileName];
6、//保存数据
CHPerson *person = [[CHPerson alloc]init];
person.name = self.nameTextFiled.text;
person.age = self.ageTextField.text;
person.sex = self.sexTextField.text;
//创建用于包含已经编码的person对象的数据类实例
NSMutableData *data = [[NSMutableDataalloc]init];
//创建NSKeyedArchiver编码对象KeyedArchiver,告诉其装载数据的数据对象data
NSKeyedArchiver *KeyedArchiver = [[NSKeyedArchiveralloc]initForWritingWithMutableData:data];
//归档
//使用"键-值"对编码,保存希望保存的person 即归档
[KeyedArchiver encodeObject:person forKey:@"Data"];
//[KeyedArchiver encodeObject:person2 forKey:@"Data2"];
//结束归档
[KeyedArchiver finishEncoding];
//写入数据到归档文件
[data writeToFile:plistPath atomically:YES];
7、//读取数据
//从归档文件中读出数据(读出的数据是二进制的数据流)
NSData *data = [[NSData alloc]initWithContentsOfFile:plistPath];
//创建解码对象,告诉其解码data数据
NSKeyedUnarchiver *KeyedUnarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];
//从解码对象中获得解码后的内容,给person
CHPerson *person = [KeyedUnarchiver decodeObjectForKey:@"Data"];
//结束解码
[KeyedUnarchiver finishDecoding];
self.nameTextFiled.text = person.name;
self.ageTextField.text = person.age;
self.sexTextField.text = person.sex;
下面是另外的一个示例
#import <Foundation/Foundation.h>
@interface Student : NSObject<NSCoding>
{
NSString *name;
NSInteger number;
NSArray *array;
}
- (id)initWithName:(NSString *)aname AndNumber:(NSInteger)num withArray:(NSArray *)aarray;
@end
#import "Student.h"
@implementation Student
- (id)initWithName:(NSString *)aname AndNumber:(NSInteger)num withArray:(NSArray *)aarray
{
self = [super init];
if (self) {
name = aname;
number = num;
array = [NSArray arrayWithArray:aarray];
}
returnself;
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:nameforKey:@"name"];
[aCoder encodeInteger:numberforKey:@"number"];
[aCoder encodeObject:arrayforKey:@"array"];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
[aDecoder decodeObjectForKey:@"name"];
[aDecoder decodeIntegerForKey:@"number"];
[aDecoder decodeObjectForKey:@"array"];
}
return self;
}
@end
在使用的地方 这样去使用
NSArray *array = [NSArray arrayWithObjects:@"wqe",@"asda",@"gsgdg",@"asdad", nil];
Student *student1 = [[Student alloc] initWithName:@"陈浩" AndNumber:100601102 withArray:array];
Student *student2 = [[Student alloc] initWithName:@"吴丹" AndNumber:100601103 withArray:array];
NSArray *studentArray = [[NSArray alloc] initWithObjects:student1,student2, nil];
NSString *path = NSHomeDirectory();
NSString *documentsPath = [pathstringByAppendingPathComponent:@"Documents"];
NSString *fileName = [documentsPathstringByAppendingPathComponent:@"Student"];
[NSKeyedArchiver archiveRootObject:studentArray toFile:fileName];
NSData *studentData = [NSKeyedArchiverarchivedDataWithRootObject:studentArray ];
NSArray *studentArray2 = [NSKeyedUnarchiver unarchiveObjectWithData:studentData ];
NSLog(@"studentArray = %@,studentData = %@,studentArray2 = %@",studentArray,studentData,studentArray2);