#import <Foundation/Foundation.h>
@interface iOSStudent : NSObject <NSCoding>
@property (nonatomic, copy) NSString * name;
@property (nonatomic, copy) NSString * ID;
@property (nonatomic, assign)NSUInteger age;
@end
2、学生类实现文件
#import "iOSStudent.h"
@implementation iOSStudent
- (void)dealloc
{
self.name = nil;
self.ID = nil;
[super dealloc];
}
#pragma mark - 实现协议中的方法
#pragma mark 归档方法
- (void)encodeWithCoder:(NSCoder *)aCoder
{
//当前对象被归档时,会调用这个方法,参数aCoder是编码器,是负责归档的对象
//要使用归档当前对象的编码器,归档当前对象的成员
//设置key是为了解归档时,还原数据
[aCoder encodeObject:self.name forKey:@"name"];
[aCoder encodeObject:self.ID forKey:@"ID"];
[aCoder encodeInteger:self.age forKey:@"age"];
}
#pragma mark 解归档方法
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init]) {
//aDecoder是一个解归档器,当它解归档当前对象时,把自己也作为参数传进来。
self.name = [aDecoder decodeObjectForKey:@"name"];
self.ID = [aDecoder decodeObjectForKey:@"ID"];
self.age = [aDecoder decodeIntegerForKey:@"age"];
}
return self;
}
@end
#import <Foundation/Foundation.h>
@interface iOSClass : NSObject <NSCoding>
@property (nonatomic,copy)NSString * className;
//添加学生信息
- (void)addStudentWithName:(NSString *)name ID:(NSString *)ID age:(NSUInteger)age;
//打印学生信息
- (void)showStudents;
@end
4、班级类实现文件
#import "iOSClass.h"
#import "iOSStudent.h"
@implementation iOSClass
{
NSMutableArray * _studentsArrayM;
}
- (void)dealloc
{
self.className = nil;
[_studentsArrayM release];
[super dealloc];
}
- (id)init
{
if (self = [super init]) {
//创建班级对象,同时实例化数组对象
_studentsArrayM = [[NSMutableArray alloc] init];
}
return self;
}
#pragma mark - 添加学生信息
- (void)addStudentWithName:(NSString *)name ID:(NSString *)ID age:(NSUInteger)age
{
//创建学生,添加到数组里
iOSStudent * stu = [[iOSStudent alloc] init];
stu.name = name;
stu.age = age;
stu.ID = ID;
[_studentsArrayM addObject:stu];
[stu release];
}
#pragma mark - 打印学生信息
- (void)showStudents
{
NSMutableString * str = [[NSMutableString alloc] init];
for (iOSStudent * stu in _studentsArrayM) {
[str appendFormat:@"姓名:%@ 年龄:%ld 学号:%@\n", stu.name, stu.age, stu.ID ];
}
NSLog(@"\n%@", str);
[str release];
}
#pragma mark - 实现协议中的方法
#pragma mark 归档方法
- (void)encodeWithCoder:(NSCoder *)aCoder
{
//直接在给数组加上个键students归档,归档时会进入数组里遍历没一个学生,对每一个学生再进行归档(转二进制)
[aCoder encodeObject:_studentsArrayM forKey:@"students"];
}
#pragma mark 解归档,是要讲NSData中的数据取出来,生成对象,因此需要构造方法
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init]) {
//直接使用键students解档
_studentsArrayM = [[aDecoder decodeObjectForKey:@"students"] retain];
//解归档时,如果解出的数据是一个对象,赋值给指针需要retain。
//学生类用的是属性,本身带copy,所以没写retain。
}
return self;
}
@end
5、main函数
#import <Foundation/Foundation.h>
#import "iOSClass.h"
#import "iOSStudent.h"
#define PATH @"/Users/qianfeng/Desktop/file.txt"
int main(int argc, const char * argv[])
{
@autoreleasepool {
#if 1
iOSClass * class = [[iOSClass alloc] init];
class.className = @"iOS好程序员8期";
[class addStudentWithName:@"张三" ID:@"三七二十一" age:23];
[class addStudentWithName:@"李四" ID:@"七八五十六" age:24];
[class addStudentWithName:@"王五" ID:@"九九八十一" age:25];
[class showStudents];
/*-------------归档操作---------------*/
//创建一个可变的二进制对象/数据包对象
NSMutableData * data = [[NSMutableData alloc] init];
//ka本身是个归档工具,相当于档案管理员,负责将数据整理,填入档案包。
NSKeyedArchiver * ka = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
//将class放入数据包
[ka encodeObject:class forKey:@"class"];
//同一个包里可以放入多个对象
//封口
[ka finishEncoding];
[ka release];
[class release];
[data writeToFile:PATH atomically:YES];
[data release];
#else
//从文件中读取数据
NSData * data =[[NSData alloc] initWithContentsOfFile:PATH];
//创建解归档管理员,负责将包中数据取出,整理还原。
NSKeyedUnarchiver * kua = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
//取出包中数据
iOSClass * class = [[kua decodeObjectForKey:@"class"] retain];
//封口
[kua finishDecoding];
[class showStudents];
[class release];
[kua release];
[data release];
#endif
}
return 0;
}
原理解释:
归档操作:
//第一步:把数据转换成二进制数据NSData
NSMutableData *data = [[NSMutableData alloc] init];
//创建归档管理器,并传入需归档的二进制数据
NSKeyedArchiver *ka = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
//归档管理器归档
[ka encodeObject:class forKey:@"class"];
//关闭归档管理器
[ka finishEncoding];
//把二进制文件写入到本地文件中
[data writeToFile:PATH atomically:YES];