归档 其实就是数据序列化(和java中的stream是一样的),将其编码成 0 1 序列。目的就是为了能在网络上传递数据 例如:上传图片到服务器,还用于可以将一些自定义的类保存到本地。
【归档步骤】
1.需要归档的数据结构中,任何对象都必须遵从归档协议NSCoding.实现相关方法
【注】无需考虑NSString,NSArray,NSDictionary三个官方类,它们已经遵从过协议,实现方法了。
//那么这里还需要遵从协议的时班级和学生了。
/2.使用KeyedAchiever进行归档
【解档步骤】
1.首先要确定你拥有同样的数据结构
2.使用KeyedUnAchiever进行解归档
注意:非ARC模式下,解归档必须retain,字符串的话,必须copy。
这是因为解归档是在内存解析,解析后的数据,是保存到栈区上的,而栈区上的数据,是系统自动管理的,它有可能在这段解归档程序结束后,就被弹栈销毁。使用了retain之后,就会调用copy,然后再堆区上开辟一个该数据结构的空间,深拷贝。这样这个解归档的数据才能有效的被使用。
main.m
#import <Foundation/Foundation.h>
#import "AZClass.h"
int main(int argc,const char * argv[])
{
@autoreleasepool {
#if 0
AZClass *class1=[[AZClass alloc] init];
[class1 addStuentWithName:@"张三" andAge:21];
[class1 addStuentWithName:@"李四" andAge:26];
[class1 addStuentWithName:@"王五" andAge:20];
[class1 addStuentWithName:@"赵六" andAge:17];
//归档其实就是数据序列化(和java中的stream是一样的),将其编码成 0 1序列。目的就是为了能在网络上传递数据 例如:上传图片到服务器。
//【归档步骤】
//1.需要归档的数据结构中,任何对象都必须遵从归档协议NSCoding.实现相关方法
//【注】无需考虑NSString,NSArray,NSDictionary三个官方类,它们已经遵从过协议,实现方法了。
//那么这里还需要遵从协议的时班级和学生了。
//2.使用KeyedAchiever进行归档
NSMutableData *data=[[NSMutableData alloc] init];
NSKeyedArchiver *arc=[[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
//归档class1
[arc encodeObject:class1 forKey:@"class1"];
[arc finishEncoding];
//此时data中存储的是将class1这个对象转换成 0 1的序列
//一个NSKeyedArchiver的对象可以归档很多的对象
//第一个参数表示文件的路径---/Users/student/guidang(文件夹)file是文件名,没有该文件则会自动创建该文件
//第二个参数表示是否是原子性操作
[data writeToFile:@"/Users/student/guidang/file" atomically:YES];
[arc release];
[class1 release];
[data release];
#else
//1.首先要确定你拥有同样的数据结构
//2.使用KeyedUnAchiever进行解归档
//将数据读出来
NSData * data = [[NSDataalloc] initWithContentsOfFile:@"/Users/student/guidang/file"];
//解归档
NSKeyedUnarchiver * unarchiver = [[NSKeyedUnarchiveralloc] initForReadingWithData:data];
AZClass * class2 = [[unarchiver decodeObjectForKey:@"class1"] retain];//注意:一定要使用retain
[unarchiverfinishDecoding];
[class2showStuent];
[class2release];
[unarchiverrelease];
[datarelease];
#endif
Student
#import <Foundation/Foundation.h>
@interface Student :NSObject <NSCoding>
@property (nonatomic,copy)NSString *name;
@property (nonatomic,assign)int age;
@end
#import "Student.h"
@implementation Student
-(void)dealloc
{
[self.namerelease];
[superdealloc];
}
#pragma mark - 实现归档协议NSCoding的方法
//用于归档的方法
- (void)encodeWithCoder:(NSCoder *)aCoder
{
//当Student被归档,这个方法会被委托,Student需要在这个方法里归档自己的子对象
//那么Stuent里有两个成员变量,name和age,则需要将name和age都归档
[aCoderencodeObject:self.nameforKey:@"name"];
// NSNumber *ageNumber=[NSNumber numberWithInt:self.age];
// [aCoder encodeObject:ageNumber forKey:@"age"];
[aCoder encodeInteger:self.ageforKey:@"age"];
}
//用于解归档的方法
- (id)initWithCoder:(NSCoder *)aDecoder
{
//当Student解归档,这个方法会被委托,Student需要在这个方法里还原自己的子对象
if (self=[superinit]) {
self.name=[aDecoderdecodeObjectForKey:@"name"];
self.age=[aDecoderdecodeIntegerForKey:@"age"];
//self.name自带copy
//self.age不是对象
}
return self;
}
@end
#import <Foundation/Foundation.h>
@interface AZClass :NSObject <NSCoding>
-(void)addStuentWithName:(NSString *)newName andAge:(int)newAge;
-(void)showStuent;
@end
#import "AZClass.h"
#import "Student.h"
@implementation AZClass
{
NSMutableArray *_array;
}
-(id)init
{
if (self=[superinit]) {
_array=[[NSMutableArrayalloc] init];
}
return self;
}
-(void)dealloc
{
[_arrayrelease];
[superdealloc];
}
-(void)addStuentWithName:(NSString *)newName andAge:(int)newAge
{
Student *stu=[[Studentalloc] init];
stu.name=newName;
stu.age=newAge;
[_arrayaddObject:stu];
[sturelease];
}
-(void)showStuent
{
NSLog(@"--------------------------");
for (Student *stuin _array) {
NSLog(@"name=%@,age=%d",stu.name,stu.age);
}
NSLog(@"--------------------------");
}
#pragma mark - 实现归档协议NSCoding的方法
//用于归档的方法
- (void)encodeWithCoder:(NSCoder *)aCoder
{
//当class被归档,这个方法会被委托,class需要在这个方法里归档自己的子对象
//那么class里有一个_array的成员变量
[aCoder encodeObject:_arrayforKey:@"array"];
}
//用于解归档的方法
- (id)initWithCoder:(NSCoder *)aDecoder
{
//当class解归档,这个方法会被委托,class需要在这个方法里还原自己的子对象
if (self=[superinit]) {
//解归档必须retain
_array = [[aDecoder decodeObjectForKey:@"array"] retain];
}
return self;
}
@end